2 * VoIP calls summary addition for Wireshark
6 * Copyright 2004, Ericsson , Spain
7 * By Francisco Alcoba <francisco.alcoba@ericsson.com>
9 * based on h323_calls_dlg.c
10 * Copyright 2004, Iskratel, Ltd, Kranj
11 * By Miha Jemec <m.jemec@iskratel.si>
13 * H323, RTP and Graph Support
14 * By Alejandro Vaquero, alejandro.vaquero@verso.com
15 * Copyright 2005, Verso Technologies Inc.
17 * Wireshark - Network traffic analyzer
18 * By Gerald Combs <gerald@wireshark.org>
19 * Copyright 1998 Gerald Combs
21 * This program is free software; you can redistribute it and/or
22 * modify it under the terms of the GNU General Public License
23 * as published by the Free Software Foundation; either version 2
24 * of the License, or (at your option) any later version.
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
31 * You should have received a copy of the GNU General Public License
32 * along with this program; if not, write to the Free Software
33 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
46 #include <epan/epan.h>
47 #include <epan/packet.h>
48 #include "epan/filesystem.h"
50 #include <epan/stat_cmd_args.h>
51 #include <epan/to_str.h>
52 #include <epan/address.h>
53 #include <epan/addr_resolv.h>
54 #include <epan/dissectors/packet-h248.h>
56 #include "../globals.h"
57 #include "../stat_menu.h"
59 #include "gtk/graph_analysis.h"
60 #include "gtk/voip_calls_dlg.h"
61 #include "gtk/voip_calls.h"
62 #include "gtk/gui_stat_menu.h"
63 #include "gtk/dlg_utils.h"
64 #include "gtk/gui_utils.h"
65 #include "gtk/gtkglobals.h"
66 #include "gtk/stock_icons.h"
68 #include "simple_dialog.h"
70 #ifdef HAVE_LIBPORTAUDIO
71 #include "gtk/rtp_analysis.h"
72 #include "gtk/rtp_player.h"
73 #endif /* HAVE_LIBPORTAUDIO */
75 #include "gtk/old-gtk-compat.h"
77 /****************************************************************************/
78 /* pointer to the one and only dialog window */
79 static GtkWidget *voip_calls_dlg = NULL;
81 static GtkListStore *list_store = NULL;
82 static GtkTreeIter list_iter;
83 static GtkWidget *list = NULL;
85 static GtkWidget *top_label = NULL;
86 static GtkWidget *status_label = NULL;
88 /*static GtkWidet *bt_unselect = NULL;*/
89 static GtkWidget *bt_filter = NULL;
90 static GtkWidget *bt_graph = NULL;
91 #ifdef HAVE_LIBPORTAUDIO
92 static GtkWidget *bt_player = NULL;
93 #endif /* HAVE_LIBPORTAUDIO */
95 static guint32 calls_nb = 0; /* number of displayed calls */
96 static guint32 calls_ns = 0; /* number of selected calls */
98 static graph_analysis_data_t *graph_analysis_data = NULL;
104 CALL_COL_INITIAL_SPEAKER,
112 NUM_COLS /* The number of columns */
116 /****************************************************************************/
118 voip_calls_remove_tap_listener(void)
120 /* Remove the calls tap listener */
121 remove_tap_listener_sip_calls();
122 remove_tap_listener_isup_calls();
123 remove_tap_listener_mtp3_calls();
124 remove_tap_listener_h225_calls();
125 remove_tap_listener_h245dg_calls();
126 remove_tap_listener_q931_calls();
127 remove_tap_listener_h248_calls();
128 remove_tap_listener_sccp_calls();
129 remove_tap_listener_sdp_calls();
130 remove_tap_listener_rtp();
131 if (find_tap_id("unistim")) { /* The plugin may be missing */
132 remove_tap_listener_unistim_calls();
134 if (find_tap_id("voip")) {
135 remove_tap_listener_voip_calls();
137 remove_tap_listener_rtp_event();
138 remove_tap_listener_mgcp_calls();
139 remove_tap_listener_actrace_calls();
140 remove_tap_listener_skinny_calls();
141 remove_tap_listener_iax2_calls();
142 remove_tap_listener_t38();
145 /****************************************************************************/
147 /****************************************************************************/
149 voip_calls_on_destroy(GObject *object _U_, gpointer user_data _U_)
151 /* remove_tap_listeners */
152 voip_calls_remove_tap_listener();
154 /* Clean up memory used by calls tap */
155 voip_calls_dlg_reset(NULL);
157 /* Note that we no longer have a "VoIP Calls" dialog box. */
158 voip_calls_dlg = NULL;
160 /* Clean up graph analysis memory */
161 g_free(graph_analysis_data);
162 graph_analysis_data = NULL;
165 /****************************************************************************/
167 voip_calls_on_unselect(GtkButton *button _U_, gpointer user_data _U_)
169 /*gtk_widget_set_sensitive(bt_unselect, FALSE);*/
170 gtk_widget_set_sensitive(bt_filter, FALSE);
171 gtk_widget_set_sensitive(bt_graph, FALSE);
172 #ifdef HAVE_LIBPORTAUDIO
173 gtk_widget_set_sensitive(bt_player, FALSE);
174 #endif /* HAVE_LIBPORTAUDIO */
177 /****************************************************************************/
179 voip_calls_on_filter(GtkButton *button _U_, gpointer user_data _U_)
181 gchar *filter_string;
182 GString *filter_string_fwd;
183 const gchar *filter_prepend;
184 gboolean is_first = TRUE;
187 voip_calls_info_t *listinfo;
188 graph_analysis_item_t *gai;
189 size_t filter_length;
190 size_t max_filter_length = 2048; /* What's this based on ? */
193 const sip_calls_info_t *sipinfo;
194 const isup_calls_info_t *isupinfo;
195 const h323_calls_info_t *h323info;
196 const h245_address_t *h245_add = NULL;
197 const gcp_ctx_t* ctx;
199 filter_string = g_strdup(gtk_entry_get_text(GTK_ENTRY(main_display_filter_widget)));
200 filter_length = strlen(filter_string);
201 pos = (int)filter_length; /* we assume the filter won't be more than 2^31-1 octets long */
202 g_strstrip(filter_string);
204 if (strlen(filter_string) > 0)
205 filter_prepend = " or ";
208 g_free(filter_string);
210 filter_string_fwd = g_string_new(filter_prepend);
212 /* look in the Graph and get all the frame_num for this call */
213 g_string_append_printf(filter_string_fwd, "(");
215 /* Build a new filter based on frame numbers */
216 lista = g_list_first(voip_calls_get_info()->callsinfo_list);
218 listinfo = lista->data;
219 if (listinfo->selected) {
220 listb = g_list_first(voip_calls_get_info()->graph_analysis->list);
223 if (gai->conv_num == listinfo->call_num) {
224 g_string_append_printf(filter_string_fwd, "%sframe.number == %u", is_first?"":" or ", gai->fd->num);
227 listb = g_list_next(listb);
230 lista = g_list_next(lista);
233 g_string_append_printf(filter_string_fwd, ")");
234 filter_length += filter_string_fwd->len;
236 if (filter_length < max_filter_length) {
237 gtk_editable_insert_text(GTK_EDITABLE(main_display_filter_widget), filter_string_fwd->str, -1, &pos);
239 g_string_free(filter_string_fwd, TRUE);
240 filter_string_fwd = g_string_new(filter_prepend);
242 g_string_append_printf(filter_string_fwd, "(");
244 /* Build a new filter based on protocol fields */
245 lista = g_list_first(voip_calls_get_info()->callsinfo_list);
247 listinfo = lista->data;
248 if (listinfo->selected) {
250 g_string_append_printf(filter_string_fwd, " or ");
251 switch (listinfo->protocol) {
253 sipinfo = listinfo->prot_info;
254 g_string_append_printf(filter_string_fwd,
255 "(sip.Call-ID == \"%s\")",
256 sipinfo->call_identifier
260 isupinfo = listinfo->prot_info;
261 g_string_append_printf(filter_string_fwd,
262 "(isup.cic == %i and frame.number >= %i and frame.number <= %i and mtp3.network_indicator == %i and ((mtp3.dpc == %i) and (mtp3.opc == %i)) or ((mtp3.dpc == %i) and (mtp3.opc == %i)))",
263 isupinfo->cic, listinfo->start_fd->num,
264 listinfo->stop_fd->num,
265 isupinfo->ni, isupinfo->dpc, isupinfo->opc,
266 isupinfo->opc, isupinfo->dpc
270 h323info = listinfo->prot_info;
271 g_string_append_printf(filter_string_fwd,
272 "((h225.guid == %s || q931.call_ref == %x:%x || q931.call_ref == %x:%x)",
273 guid_to_str(&h323info->guid[0]),
274 (guint8) (h323info->q931_crv & 0x00ff),
275 (guint8)((h323info->q931_crv & 0xff00)>>8),
276 (guint8) (h323info->q931_crv2 & 0x00ff),
277 (guint8)((h323info->q931_crv2 & 0xff00)>>8));
278 listb = g_list_first(h323info->h245_list);
280 h245_add = listb->data;
281 g_string_append_printf(filter_string_fwd,
282 " || (ip.addr == %s && tcp.port == %d && h245)",
283 ip_to_str((guint8 *)(h245_add->h245_address.data)), h245_add->h245_port);
284 listb = g_list_next(listb);
286 g_string_append_printf(filter_string_fwd, ")");
289 ctx = listinfo->prot_info;
290 g_string_append_printf(filter_string_fwd,
291 "(h248.ctx == 0x%x)", ctx->id);
294 /* placeholder to assure valid display filter expression */
295 g_string_append_printf(filter_string_fwd,
301 lista = g_list_next(lista);
304 g_string_append_printf(filter_string_fwd, ")");
305 gtk_editable_insert_text(GTK_EDITABLE(main_display_filter_widget), filter_string_fwd->str, -1, &pos);
308 g_string_free(filter_string_fwd, TRUE);
311 /****************************************************************************/
313 voip_calls_on_select_all(GtkButton *button _U_, gpointer user_data _U_)
315 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list));
316 gtk_tree_selection_select_all(selection);
319 /****************************************************************************/
321 on_graph_bt_clicked(GtkButton *button _U_, gpointer user_data _U_)
323 graph_analysis_item_t *gai;
326 voip_calls_info_t *listinfo;
328 /* reset the "display" parameter in graph analysis */
329 listb = g_list_first(voip_calls_get_info()->graph_analysis->list);
332 gai->display = FALSE;
333 listb = g_list_next(listb);
336 /* set the display for selected calls */
337 lista = g_list_first(voip_calls_get_info()->callsinfo_list);
339 listinfo = lista->data;
340 if (listinfo->selected) {
341 listb = g_list_first(voip_calls_get_info()->graph_analysis->list);
344 if (gai->conv_num == listinfo->call_num) {
347 listb = g_list_next(listb);
350 lista = g_list_next(lista);
353 /* create or refresh the graph windows */
354 if (graph_analysis_data->dlg.window == NULL)
355 graph_analysis_create(graph_analysis_data); /* create the window */
357 graph_analysis_update(graph_analysis_data); /* refresh it */
360 /****************************************************************************/
361 #ifdef HAVE_LIBPORTAUDIO
363 on_player_bt_clicked(GtkButton *button _U_, gpointer user_data _U_)
365 rtp_player_init(voip_calls_get_info());
367 #endif /* HAVE_LIBPORTAUDIO */
369 /****************************************************************************/
370 /* when the user selects a row in the calls list */
372 voip_calls_mark_selected(GtkTreeModel *model, GtkTreePath *path _U_, GtkTreeIter *iter, gpointer data)
374 GtkTreeSelection *selection = (GtkTreeSelection *)data;
375 voip_calls_info_t* strinfo;
377 gtk_tree_model_get(model, iter, CALL_COL_DATA, &strinfo, -1);
378 strinfo->selected = gtk_tree_selection_iter_is_selected(selection, iter);
384 voip_calls_on_select_row_cb(GtkTreeSelection *selection, gpointer data _U_)
386 gchar label_text[80];
388 gtk_tree_model_foreach(GTK_TREE_MODEL(list_store), voip_calls_mark_selected, selection);
390 calls_ns = gtk_tree_selection_count_selected_rows(selection);
392 g_snprintf(label_text, 80,
393 "Detected %u VoIP %s. Selected %u %s.",
395 plurality(calls_nb, "Call", "Calls"),
397 plurality(calls_ns, "Call", "Calls"));
398 gtk_label_set_text(GTK_LABEL(top_label), label_text);
400 gtk_widget_set_sensitive(bt_filter, calls_ns ? TRUE : FALSE);
401 gtk_widget_set_sensitive(bt_graph, calls_ns ? TRUE : FALSE);
402 #ifdef HAVE_LIBPORTAUDIO
403 gtk_widget_set_sensitive(bt_player, calls_ns ? TRUE : FALSE);
404 #endif /* HAVE_LIBPORTAUDIO */
407 /****************************************************************************/
408 /* Tree view constructors */
409 /****************************************************************************/
410 /* append a line to list */
412 add_to_list_store(voip_calls_info_t* strinfo)
414 gchar field[NUM_COLS][50];
415 isup_calls_info_t *isupinfo;
416 h323_calls_info_t *h323info;
417 gboolean flag = FALSE;
419 g_snprintf(field[CALL_COL_INITIAL_SPEAKER], 30, "%s", get_addr_name(&(strinfo->initial_speaker)));
420 g_snprintf(field[CALL_COL_FROM], 50, "%s", strinfo->from_identity);
421 g_snprintf(field[CALL_COL_TO], 50, "%s", strinfo->to_identity);
422 g_snprintf(field[CALL_COL_PROTOCOL], 15, "%s",
423 ((strinfo->protocol==VOIP_COMMON)&&strinfo->protocol_name)?
424 strinfo->protocol_name:voip_protocol_name[strinfo->protocol]);
425 g_snprintf(field[CALL_COL_STATE], 15, "%s", voip_call_state_name[strinfo->call_state]);
427 /* Add comments based on the protocol */
428 switch (strinfo->protocol) {
430 isupinfo = strinfo->prot_info;
431 g_snprintf(field[CALL_COL_COMMENTS],30, "%i-%i -> %i-%i", isupinfo->ni, isupinfo->opc,
432 isupinfo->ni, isupinfo->dpc);
435 h323info = strinfo->prot_info;
436 if (strinfo->call_state == VOIP_CALL_SETUP)
437 flag = h323info->is_faststart_Setup;
439 if ((h323info->is_faststart_Setup == TRUE) && (h323info->is_faststart_Proc == TRUE))
441 g_snprintf(field[CALL_COL_COMMENTS],35, "Tunneling: %s Fast Start: %s",
442 (h323info->is_h245Tunneling==TRUE?"ON":"OFF"),
443 (flag==TRUE?"ON":"OFF"));
446 field[CALL_COL_COMMENTS][0]='\0';
447 if (strinfo->call_comment)
448 g_snprintf(field[CALL_COL_COMMENTS],30, "%s", strinfo->call_comment);
451 field[CALL_COL_COMMENTS][0]='\0';
454 /* Acquire an iterator */
455 gtk_list_store_append(list_store, &list_iter);
457 /* Fill the new row */
458 gtk_list_store_set(list_store, &list_iter,
459 CALL_COL_START_TIME, nstime_to_sec(&strinfo->start_fd->rel_ts),
460 CALL_COL_STOP_TIME, nstime_to_sec(&strinfo->stop_fd->rel_ts),
461 CALL_COL_INITIAL_SPEAKER, &field[CALL_COL_INITIAL_SPEAKER][0],
462 CALL_COL_FROM, &field[CALL_COL_FROM][0],
463 CALL_COL_TO, &field[CALL_COL_TO][0],
464 CALL_COL_PROTOCOL, &field[CALL_COL_PROTOCOL][0],
465 CALL_COL_PACKETS, strinfo->npackets,
466 CALL_COL_STATE, &field[CALL_COL_STATE][0],
467 CALL_COL_COMMENTS, &field[CALL_COL_COMMENTS][0],
468 CALL_COL_DATA, strinfo,
474 /****************************************************************************/
475 /* Create list view */
477 create_list_view(void)
479 GtkTreeViewColumn *column;
480 GtkCellRenderer *renderer;
481 GtkTreeSortable *sortable;
482 GtkTreeView *list_view;
483 GtkTreeSelection *selection;
485 /* Create the store */
486 list_store = gtk_list_store_new(NUM_COLS, /* Total number of columns XXX */
487 G_TYPE_DOUBLE, /* Start Time */
488 G_TYPE_DOUBLE, /* Stop Time */
489 G_TYPE_STRING, /* Initial Speaker */
490 G_TYPE_STRING, /* From */
491 G_TYPE_STRING, /* To */
492 G_TYPE_STRING, /* Protocol */
493 G_TYPE_UINT, /* Packets */
494 G_TYPE_STRING, /* State */
495 G_TYPE_STRING, /* Comments */
496 G_TYPE_POINTER /* Data */
500 list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(list_store));
502 /* The view now holds a reference. We can get rid of our own reference */
503 g_object_unref(G_OBJECT(list_store));
505 list_view = GTK_TREE_VIEW(list);
506 sortable = GTK_TREE_SORTABLE(list_store);
508 /* Speed up the list display */
509 gtk_tree_view_set_fixed_height_mode(list_view, TRUE);
511 /* Setup the sortable columns */
512 gtk_tree_sortable_set_sort_column_id(sortable, CALL_COL_START_TIME, GTK_SORT_ASCENDING);
513 gtk_tree_view_set_headers_clickable(list_view, FALSE);
516 renderer = gtk_cell_renderer_text_new();
517 g_object_set(G_OBJECT(renderer), "xalign", 1.0, NULL); /* right align */
518 g_object_set(G_OBJECT(renderer), "xpad", 10, NULL);
519 column = gtk_tree_view_column_new_with_attributes("Start Time", renderer,
520 "text", CALL_COL_START_TIME,
522 gtk_tree_view_column_set_sort_column_id(column, CALL_COL_START_TIME);
523 gtk_tree_view_column_set_resizable(column, TRUE);
524 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
525 gtk_tree_view_column_set_min_width(column, 60);
526 gtk_tree_view_column_set_fixed_width(column, 100);
527 /* Add the column to the view. */
528 gtk_tree_view_append_column(list_view, column);
531 renderer = gtk_cell_renderer_text_new();
532 g_object_set(G_OBJECT(renderer), "xalign", 1.0, NULL); /* right align */
533 g_object_set(G_OBJECT(renderer), "xpad", 10, NULL);
534 column = gtk_tree_view_column_new_with_attributes("Stop Time", renderer,
535 "text", CALL_COL_STOP_TIME,
537 gtk_tree_view_column_set_sort_column_id(column, CALL_COL_STOP_TIME);
538 gtk_tree_view_column_set_resizable(column, TRUE);
539 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
540 gtk_tree_view_column_set_min_width(column, 60);
541 gtk_tree_view_column_set_fixed_width(column, 100);
542 gtk_tree_view_append_column(list_view, column);
544 /* Initial Speaker */
545 renderer = gtk_cell_renderer_text_new();
546 column = gtk_tree_view_column_new_with_attributes("Initial Speaker", renderer,
547 "text", CALL_COL_INITIAL_SPEAKER,
549 gtk_tree_view_column_set_sort_column_id(column, CALL_COL_INITIAL_SPEAKER);
550 gtk_tree_view_column_set_resizable(column, TRUE);
551 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
552 gtk_tree_view_column_set_min_width(column, 80);
553 gtk_tree_view_column_set_fixed_width(column, 120);
554 gtk_tree_view_append_column(list_view, column);
557 renderer = gtk_cell_renderer_text_new();
558 column = gtk_tree_view_column_new_with_attributes("From", renderer,
559 "text", CALL_COL_FROM,
561 gtk_tree_view_column_set_sort_column_id(column, CALL_COL_FROM);
562 gtk_tree_view_column_set_resizable(column, TRUE);
563 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
564 gtk_tree_view_column_set_min_width(column, 130);
565 gtk_tree_view_column_set_fixed_width(column, 140);
566 gtk_tree_view_append_column(list_view, column);
569 renderer = gtk_cell_renderer_text_new();
570 column = gtk_tree_view_column_new_with_attributes("To", renderer,
573 gtk_tree_view_column_set_sort_column_id(column, CALL_COL_TO);
574 gtk_tree_view_column_set_resizable(column, TRUE);
575 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
576 gtk_tree_view_column_set_min_width(column, 130);
577 gtk_tree_view_column_set_fixed_width(column, 140);
578 gtk_tree_view_append_column(list_view, column);
581 renderer = gtk_cell_renderer_text_new();
582 column = gtk_tree_view_column_new_with_attributes("Protocol", renderer,
583 "text", CALL_COL_PROTOCOL,
585 gtk_tree_view_column_set_sort_column_id(column, CALL_COL_PROTOCOL);
586 gtk_tree_view_column_set_resizable(column, TRUE);
587 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
588 gtk_tree_view_column_set_min_width(column, 50);
589 gtk_tree_view_column_set_fixed_width(column, 80);
590 gtk_tree_view_append_column(list_view, column);
593 renderer = gtk_cell_renderer_text_new();
594 g_object_set(G_OBJECT(renderer), "xalign", 1.0, NULL); /* right align numbers */
595 g_object_set(G_OBJECT(renderer), "xpad", 10, NULL);
596 column = gtk_tree_view_column_new_with_attributes("Packets", renderer,
597 "text", CALL_COL_PACKETS,
599 gtk_tree_view_column_set_sort_column_id(column, CALL_COL_PACKETS);
600 gtk_tree_view_column_set_resizable(column, TRUE);
601 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
602 gtk_tree_view_column_set_min_width(column, 70);
603 gtk_tree_view_column_set_fixed_width(column, 80);
604 gtk_tree_view_append_column(list_view, column);
607 renderer = gtk_cell_renderer_text_new();
608 column = gtk_tree_view_column_new_with_attributes("State", renderer,
609 "text", CALL_COL_STATE,
611 gtk_tree_view_column_set_sort_column_id(column, CALL_COL_STATE);
612 gtk_tree_view_column_set_resizable(column, TRUE);
613 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
614 gtk_tree_view_column_set_min_width(column, 60);
615 gtk_tree_view_column_set_fixed_width(column, 80);
616 gtk_tree_view_append_column(list_view, column);
619 renderer = gtk_cell_renderer_text_new();
620 column = gtk_tree_view_column_new_with_attributes("Comments", renderer,
621 "text", CALL_COL_COMMENTS,
623 gtk_tree_view_column_set_sort_column_id(column, CALL_COL_COMMENTS);
624 gtk_tree_view_column_set_resizable(column, TRUE);
625 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
626 gtk_tree_view_column_set_min_width(column, 100);
627 gtk_tree_view_column_set_fixed_width(column, 140);
628 gtk_tree_view_append_column(list_view, column);
630 /* Now enable the sorting of each column */
631 gtk_tree_view_set_rules_hint(list_view, TRUE);
632 gtk_tree_view_set_headers_clickable(list_view, TRUE);
634 /* Setup the selection handler */
635 selection = gtk_tree_view_get_selection(list_view);
636 gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
638 g_signal_connect(G_OBJECT(selection), "changed", /* select_row */
639 G_CALLBACK(voip_calls_on_select_row_cb),
644 /****************************************************************************/
646 /****************************************************************************/
648 voip_calls_dlg_create(void)
650 GtkWidget *voip_calls_dlg_w;
652 GtkWidget *scrolledwindow;
653 GtkWidget *hbuttonbox;
655 GtkWidget *bt_select_all;
656 const gchar *title_name_ptr;
659 title_name_ptr = cf_get_display_name(&cfile);
660 win_name = g_strdup_printf("%s - VoIP Calls", title_name_ptr);
661 voip_calls_dlg_w = dlg_window_new(win_name); /* transient_for top_level */
662 gtk_window_set_destroy_with_parent(GTK_WINDOW(voip_calls_dlg_w), TRUE);
664 gtk_window_set_default_size(GTK_WINDOW(voip_calls_dlg_w), 1000, 350);
666 main_vb = gtk_vbox_new(FALSE, 0);
667 gtk_container_add(GTK_CONTAINER(voip_calls_dlg_w), main_vb);
668 gtk_container_set_border_width(GTK_CONTAINER (main_vb), 12);
670 top_label = gtk_label_new("Detected 0 VoIP Calls. Selected 0 Calls.");
671 gtk_box_pack_start(GTK_BOX (main_vb), top_label, FALSE, FALSE, 8);
673 scrolledwindow = scrolled_window_new(NULL, NULL);
674 gtk_box_pack_start(GTK_BOX (main_vb), scrolledwindow, TRUE, TRUE, 0);
677 gtk_container_add(GTK_CONTAINER(scrolledwindow), list);
678 gtk_widget_show(voip_calls_dlg_w);
680 status_label = gtk_label_new("Total: Calls: 0 Start packets: 0 Completed calls: 0 Rejected calls: 0");
681 gtk_box_pack_start(GTK_BOX(main_vb), status_label, FALSE, FALSE, 8);
684 hbuttonbox = gtk_hbutton_box_new();
685 gtk_box_pack_start(GTK_BOX(main_vb), hbuttonbox, FALSE, FALSE, 0);
686 gtk_button_box_set_layout(GTK_BUTTON_BOX (hbuttonbox), GTK_BUTTONBOX_SPREAD);
687 gtk_box_set_spacing(GTK_BOX(hbuttonbox), 30);
689 /*bt_unselect = gtk_button_new_with_label ("Unselect");
690 gtk_container_add (GTK_CONTAINER (hbuttonbox), bt_unselect);
691 gtk_widget_set_tooltip_text (bt_unselect, "Unselect this conversation");*/
693 bt_filter = gtk_button_new_from_stock(WIRESHARK_STOCK_PREPARE_FILTER);
694 gtk_container_add(GTK_CONTAINER(hbuttonbox), bt_filter);
695 gtk_widget_set_tooltip_text(bt_filter, "Prepare a display filter of the selected conversation");
697 bt_graph = gtk_button_new_from_stock(WIRESHARK_STOCK_VOIP_FLOW);
698 gtk_container_add(GTK_CONTAINER(hbuttonbox), bt_graph);
699 gtk_widget_show(bt_graph);
700 g_signal_connect(bt_graph, "clicked", G_CALLBACK(on_graph_bt_clicked), NULL);
701 gtk_widget_set_tooltip_text(bt_graph, "Show a flow graph of the selected calls.");
703 #ifdef HAVE_LIBPORTAUDIO
704 bt_player = gtk_button_new_from_stock(WIRESHARK_STOCK_AUDIO_PLAYER);
705 gtk_container_add(GTK_CONTAINER(hbuttonbox), bt_player);
706 gtk_widget_show(bt_player);
707 g_signal_connect(bt_player, "clicked", G_CALLBACK(on_player_bt_clicked), NULL);
708 gtk_widget_set_tooltip_text(bt_player, "Launch the RTP player to listen the selected calls.");
709 #endif /* HAVE_LIBPORTAUDIO */
711 bt_select_all = gtk_button_new_from_stock(GTK_STOCK_SELECT_ALL);
712 gtk_container_add(GTK_CONTAINER(hbuttonbox), bt_select_all);
713 #if GTK_CHECK_VERSION(2,18,0)
714 gtk_widget_set_can_default(bt_select_all, TRUE);
716 GTK_WIDGET_SET_FLAGS(bt_select_all, GTK_CAN_DEFAULT);
718 gtk_widget_set_tooltip_text(bt_select_all, "Select all the calls");
720 bt_close = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
721 gtk_container_add(GTK_CONTAINER (hbuttonbox), bt_close);
722 #if GTK_CHECK_VERSION(2,18,0)
723 gtk_widget_set_can_default(bt_close, TRUE);
725 GTK_WIDGET_SET_FLAGS(bt_close, GTK_CAN_DEFAULT);
727 gtk_widget_set_tooltip_text(bt_close, "Close this dialog");
729 /*g_signal_connect(bt_unselect, "clicked", G_CALLBACK(voip_calls_on_unselect), NULL);*/
730 g_signal_connect(bt_filter, "clicked", G_CALLBACK(voip_calls_on_filter), NULL);
732 window_set_cancel_button(voip_calls_dlg_w, bt_close, window_cancel_button_cb);
734 g_signal_connect(voip_calls_dlg_w, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
735 g_signal_connect(voip_calls_dlg_w, "destroy", G_CALLBACK(voip_calls_on_destroy), NULL);
736 g_signal_connect(bt_select_all, "clicked", G_CALLBACK(voip_calls_on_select_all), NULL);
738 gtk_widget_show_all(voip_calls_dlg_w);
739 window_present(voip_calls_dlg_w);
741 voip_calls_on_unselect(NULL, NULL);
743 voip_calls_dlg = voip_calls_dlg_w;
749 /****************************************************************************/
751 /****************************************************************************/
753 /****************************************************************************/
754 /* update the contents of the list view */
755 /* list: pointer to list of voip_calls_info_t* */
757 voip_calls_dlg_update(GList *listx)
759 gchar label_text[256];
760 if (voip_calls_dlg != NULL) {
763 gtk_list_store_clear(list_store);
765 g_snprintf(label_text, sizeof(label_text),
766 "Total: Calls: %u Start packets: %u Completed calls: %u Rejected calls: %u",
767 g_list_length(voip_calls_get_info()->callsinfo_list),
768 voip_calls_get_info()->start_packets,
769 voip_calls_get_info()->completed_calls,
770 voip_calls_get_info()->rejected_calls);
771 gtk_label_set_text(GTK_LABEL(status_label), label_text);
773 listx = g_list_first(listx);
775 add_to_list_store((voip_calls_info_t*)(listx->data));
776 listx = g_list_next(listx);
779 g_snprintf(label_text, sizeof(label_text),
780 "Detected %u VoIP %s. Selected %u %s.",
782 plurality(calls_nb, "Call", "Calls"),
784 plurality(calls_ns, "Call", "Calls"));
785 gtk_label_set_text(GTK_LABEL(top_label), label_text);
789 /****************************************************************************/
790 /* draw function for tap listeners to keep the window up to date */
792 voip_calls_dlg_draw(void *ptr _U_)
794 if (voip_calls_get_info()->redraw) {
795 voip_calls_dlg_update(voip_calls_get_info()->callsinfo_list);
796 voip_calls_get_info()->redraw = FALSE;
800 /****************************************************************************/
801 /* reset function for tap listeners to clear window, if necessary */
803 voip_calls_dlg_reset(void *ptr _U_)
805 /* Clean up memory used by calls tap */
806 voip_calls_reset(voip_calls_get_info());
808 /* close the graph window if open */
809 if (graph_analysis_data && graph_analysis_data->dlg.window != NULL) {
810 window_cancel_button_cb(NULL, graph_analysis_data->dlg.window);
811 graph_analysis_data->dlg.window = NULL;
815 /****************************************************************************/
816 /* init function for tap */
818 voip_calls_init_tap(const char *dummy _U_, void* userdata _U_)
820 if (graph_analysis_data == NULL) {
821 graph_analysis_data_init();
822 /* init the Graph Analysys */
823 graph_analysis_data = graph_analysis_init();
824 graph_analysis_data->graph_info = voip_calls_get_info()->graph_analysis;
827 /* Clean up memory used by calls tap */
828 voip_calls_reset(voip_calls_get_info());
830 /* Register the tap listener */
831 sip_calls_init_tap();
832 mtp3_calls_init_tap();
833 isup_calls_init_tap();
834 h225_calls_init_tap();
835 h245dg_calls_init_tap();
836 q931_calls_init_tap();
837 h248_calls_init_tap();
838 sccp_calls_init_tap();
839 sdp_calls_init_tap();
840 /* We don't register this tap, if we don't have the unistim plugin loaded.*/
841 if (find_tap_id("unistim")) {
842 unistim_calls_init_tap();
844 if (find_tap_id("voip")) {
845 VoIPcalls_init_tap();
848 rtp_event_init_tap();
849 mgcp_calls_init_tap();
850 actrace_calls_init_tap();
851 skinny_calls_init_tap();
852 iax2_calls_init_tap();
855 /* create dialog box if necessary */
856 if (voip_calls_dlg == NULL) {
857 voip_calls_dlg_create();
859 /* There's already a dialog box; reactivate it. */
860 reactivate_window(voip_calls_dlg);
863 voip_calls_get_info()->redraw = TRUE;
864 voip_calls_dlg_draw(NULL);
865 voip_calls_get_info()->redraw = TRUE;
867 /* Scan for VoIP calls calls (redissect all packets) */
868 cf_retap_packets(&cfile);
869 gdk_window_raise(gtk_widget_get_window(voip_calls_dlg));
870 /* Tap listener will be removed and cleaned up in voip_calls_on_destroy */
874 /****************************************************************************/
875 /* entry point when called via the GTK menu */
876 #ifdef MAIN_MENU_USE_UIMANAGER
878 voip_calls_launch(GtkAction *action _U_, gpointer user_data _U_)
880 voip_calls_init_tap("", NULL);
884 voip_calls_launch(GtkWidget *w _U_, gpointer data _U_)
886 voip_calls_init_tap("", NULL);
890 /****************************************************************************/
892 register_tap_listener_voip_calls_dlg(void)
894 register_stat_cmd_arg("voip,calls", voip_calls_init_tap, NULL);
895 #ifdef MAIN_MENU_USE_UIMANAGER
897 register_stat_menu_item_stock("_VoIP Calls",
898 REGISTER_STAT_GROUP_TELEPHONY, WIRESHARK_STOCK_TELEPHONE,
899 voip_calls_launch, NULL, NULL, NULL);