aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Coleman <jamesc@dspsrv.com>2014-06-19 17:47:49 +0100
committerAnders Broman <a.broman58@gmail.com>2014-06-25 16:14:58 +0000
commit8ac87dccde4544e5397f0d741d2ec9f230971b43 (patch)
tree0646a55352122a71d41113c6de55c50bbc15c260
parent03f7a4bedc046651e82cb49d26e4fb75cc7af26b (diff)
fix_bug_10199: enhancement Telephony VoIP Call add ability to show all SIP Flows.
Add SIP Flows menu option beside VoIP Calls. Flow for all SIP message types (which have a call-id) is shown in SIP Flow. Add useful info(original flow method, response code, cseq) to comment field in conversation and flow dialogs. Change-Id: I4801a633ed9b6594b2d89629c9d6fec6352da150 Reviewed-on: https://code.wireshark.org/review/2479 Reviewed-by: Evan Huus <eapache@gmail.com> Reviewed-by: James Coleman <gaoithe@gmail.com> Reviewed-by: Anders Broman <a.broman58@gmail.com>
-rw-r--r--ui/gtk/gui_stat_menu.h1
-rw-r--r--ui/gtk/main_menubar.c2
-rw-r--r--ui/gtk/voip_calls.c69
-rw-r--r--ui/gtk/voip_calls.h9
-rw-r--r--ui/gtk/voip_calls_dlg.c23
5 files changed, 91 insertions, 13 deletions
diff --git a/ui/gtk/gui_stat_menu.h b/ui/gtk/gui_stat_menu.h
index 992193b3c1..03beef2a2d 100644
--- a/ui/gtk/gui_stat_menu.h
+++ b/ui/gtk/gui_stat_menu.h
@@ -136,6 +136,7 @@ void sctp_stat_start(GtkAction *action, gpointer user_data);
void gui_iostat_cb(GtkAction *action, gpointer user_data);
void voip_calls_launch(GtkAction *action, gpointer user_data);
+void voip_flows_launch(GtkAction *action, gpointer user_data);
void ansi_a_stat_gtk_bsmap_cb(GtkAction *action, gpointer user_data);
void ansi_a_stat_gtk_dtap_cb(GtkAction *action, gpointer user_data);
diff --git a/ui/gtk/main_menubar.c b/ui/gtk/main_menubar.c
index 6b85dd19a9..1ab235250e 100644
--- a/ui/gtk/main_menubar.c
+++ b/ui/gtk/main_menubar.c
@@ -1324,6 +1324,7 @@ static const char *ui_desc_menubar =
" <menuitem name='SMPP' action='/Telephony/smpp_commands'/>\n"
" <menuitem name='UCP' action='/Telephony/ucp_messages'/>\n"
" <menuitem name='VoIPCalls' action='/Telephony/VoIPCalls'/>\n"
+" <menuitem name='VoIPFlows' action='/Telephony/VoIPFlows'/>\n"
" </menu>\n"
" <menu name= 'ToolsMenu' action='/Tools'>\n"
" <menuitem name='FirewallACLRules' action='/Tools/FirewallACLRules'/>\n"
@@ -1789,6 +1790,7 @@ static const GtkActionEntry main_menu_bar_entries[] = {
{ "/Telephony/smpp_commands", NULL, "SM_PPOperations", NULL, NULL, G_CALLBACK(gtk_stats_tree_cb) },
{ "/Telephony/ucp_messages", NULL, "_UCP Messages", NULL, NULL, G_CALLBACK(gtk_stats_tree_cb) },
{ "/Telephony/VoIPCalls", WIRESHARK_STOCK_TELEPHONE, "_VoIP Calls", NULL, NULL, G_CALLBACK(voip_calls_launch) },
+ { "/Telephony/VoIPFlows", WIRESHARK_STOCK_TELEPHONE, "SIP _Flows", NULL, NULL, G_CALLBACK(voip_flows_launch) },
{ "/Tools/FirewallACLRules", NULL, "Firewall ACL Rules", NULL, NULL, G_CALLBACK(firewall_rule_cb) },
diff --git a/ui/gtk/voip_calls.c b/ui/gtk/voip_calls.c
index ea150c3a87..29ee319de5 100644
--- a/ui/gtk/voip_calls.c
+++ b/ui/gtk/voip_calls.c
@@ -994,6 +994,7 @@ SIPcalls_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, con
address tmp_src, tmp_dst;
gchar *frame_label = NULL;
gchar *comment = NULL;
+ gchar *old_comment = NULL;
gchar *key=NULL;
const sip_info_value_t *pi = (const sip_info_value_t *)SIPinfo;
@@ -1014,9 +1015,17 @@ SIPcalls_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, con
/* search the call information in the SIP_HASH */
callsinfo = (voip_calls_info_t *)g_hash_table_lookup(tapinfo->callsinfo_hashtable[SIP_HASH], key);
- /* not in the hash? then create a new entry if the message is INVITE -i.e. if this session is a call*/
- if ((callsinfo==NULL) &&(pi->request_method!=NULL)) {
- if (strcmp(pi->request_method,"INVITE")==0) {
+ /* Create a new flow entry if the message is INVITE in case of FLOW_ONLY_INVITES,
+ Create a new flow entry for all messages which have a method in case of FLOW_ALL.
+ Flows for REGISTER, OPTIONS, MESSAGE and other SIP methods can be seen. */
+
+ if ((callsinfo==NULL) && (pi->request_method!=NULL)) {
+
+ /* check VoIPcalls_get_flow_show_option() == FLOW_ALL or FLOW_ONLY_INVITES */
+
+ if (VoIPcalls_get_flow_show_option() == FLOW_ALL ||
+ (VoIPcalls_get_flow_show_option() == FLOW_ONLY_INVITES &&
+ strcmp(pi->request_method,"INVITE")==0)) {
callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
callsinfo->call_active_state = VOIP_ACTIVE;
callsinfo->call_state = VOIP_CALL_SETUP;
@@ -1029,16 +1038,21 @@ SIPcalls_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, con
callsinfo->protocol=VOIP_SIP;
callsinfo->prot_info=g_malloc(sizeof(sip_calls_info_t));
callsinfo->free_prot_info = free_sip_info;
+ callsinfo->call_id = g_strdup(pi->tap_call_id);
tmp_sipinfo = (sip_calls_info_t *)callsinfo->prot_info;
tmp_sipinfo->call_identifier = g_strdup(pi->tap_call_id);
tmp_sipinfo->sip_state = SIP_INVITE_SENT;
tmp_sipinfo->invite_cseq = pi->tap_cseq_number;
callsinfo->npackets = 0;
callsinfo->call_num = tapinfo->ncalls++;
+
+ /* show method in comment in conversation list dialog, user can discern different conversation types */
+ callsinfo->call_comment=g_strdup(pi->request_method);
+
tapinfo->callsinfo_list = g_list_prepend(tapinfo->callsinfo_list, callsinfo);
/* insert the call information in the SIP_HASH */
g_hash_table_insert(tapinfo->callsinfo_hashtable[SIP_HASH],
- tmp_sipinfo->call_identifier, callsinfo);
+ tmp_sipinfo->call_identifier, callsinfo);
}
}
@@ -1052,7 +1066,7 @@ SIPcalls_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, con
if (pi->request_method == NULL) {
frame_label = g_strdup_printf("%u %s", pi->response_code, pi->reason_phrase );
- comment = g_strdup("SIP Status");
+ comment = g_strdup_printf("SIP Status %u %s", pi->response_code, pi->reason_phrase );
if ((tmp_sipinfo && pi->tap_cseq_number == tmp_sipinfo->invite_cseq)&&(ADDRESSES_EQUAL(&tmp_dst,&(callsinfo->initial_speaker)))) {
if ((pi->response_code > 199) && (pi->response_code<300) && (tmp_sipinfo->sip_state == SIP_INVITE_SENT)) {
@@ -1062,6 +1076,19 @@ SIPcalls_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, con
callsinfo->call_state = VOIP_REJECTED;
tapinfo->rejected_calls++;
}
+
+ /* UPDATE comment in conversation list dialog with response code and reason.
+ Multiple code(+reason) may be appended, so skip over intermediate codes (100 trying, 183 ringing, e.t.c.)
+ TODO: is useful but not perfect, what is appended is truncated when displayed in dialog window */
+ if (pi->response_code >= 200) {
+ old_comment = callsinfo->call_comment;
+ callsinfo->call_comment=g_strdup_printf("%s %u",
+ callsinfo->call_comment,
+ pi->response_code/*, pi->reason_phrase*/);
+
+ g_free(old_comment);
+ }
+
}
}
@@ -1071,26 +1098,35 @@ SIPcalls_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, con
if ((strcmp(pi->request_method,"INVITE")==0)&&(ADDRESSES_EQUAL(&tmp_src,&(callsinfo->initial_speaker)))) {
tmp_sipinfo->invite_cseq = pi->tap_cseq_number;
callsinfo->call_state = VOIP_CALL_SETUP;
- comment = g_strdup_printf("SIP From: %s To:%s", callsinfo->from_identity, callsinfo->to_identity);
+ /* TODO: sometimes truncated when displayed in dialog window */
+ comment = g_strdup_printf("SIP INVITE From: %s To:%s Call-ID:%s CSeq:%d",
+ callsinfo->from_identity, callsinfo->to_identity,
+ callsinfo->call_id, pi->tap_cseq_number);
}
else if ((strcmp(pi->request_method,"ACK")==0)&&(pi->tap_cseq_number == tmp_sipinfo->invite_cseq)
&&(ADDRESSES_EQUAL(&tmp_src,&(callsinfo->initial_speaker)))&&(tmp_sipinfo->sip_state==SIP_200_REC)
&&(callsinfo->call_state == VOIP_CALL_SETUP)) {
callsinfo->call_state = VOIP_IN_CALL;
- comment = g_strdup("SIP Request");
+ comment = g_strdup_printf("SIP Request INVITE ACK 200 CSeq:%d", pi->tap_cseq_number);
}
else if (strcmp(pi->request_method,"BYE")==0) {
callsinfo->call_state = VOIP_COMPLETED;
tapinfo->completed_calls++;
- comment = g_strdup("SIP Request");
+ comment = g_strdup_printf("SIP Request BYE CSeq:%d", pi->tap_cseq_number);
}
else if ((strcmp(pi->request_method,"CANCEL")==0)&&(pi->tap_cseq_number == tmp_sipinfo->invite_cseq)
&&(ADDRESSES_EQUAL(&tmp_src,&(callsinfo->initial_speaker)))&&(callsinfo->call_state==VOIP_CALL_SETUP)) {
callsinfo->call_state = VOIP_CANCELLED;
tmp_sipinfo->sip_state = SIP_CANCEL_SENT;
- comment = g_strdup("SIP Request");
+ comment = g_strdup_printf("SIP Request CANCEL CSeq:%d", pi->tap_cseq_number);
} else {
- comment = g_strdup("SIP Request");
+ /* comment = g_strdup_printf("SIP %s", pi->request_method); */
+ tmp_sipinfo->invite_cseq = pi->tap_cseq_number;
+ callsinfo->call_state = VOIP_CALL_SETUP;
+ comment = g_strdup_printf("SIP %s From: %s To:%s CSeq:%d",
+ pi->request_method,
+ callsinfo->from_identity,
+ callsinfo->to_identity, pi->tap_cseq_number);
}
}
@@ -1113,6 +1149,7 @@ SIPcalls_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, con
g_free(sdp_summary);
sdp_summary = NULL;
}
+
}
tapinfo->redraw = TRUE;
@@ -4069,6 +4106,18 @@ remove_tap_listener_voip_calls(void)
have_voip_tap_listener=FALSE;
}
+/****************************************************************************/
+static flow_show_options flow_show_option=FLOW_ALL;
+
+flow_show_options VoIPcalls_get_flow_show_option(void)
+{
+ return flow_show_option;
+}
+
+void VoIPcalls_set_flow_show_option(flow_show_options option)
+{
+ flow_show_option = option;
+}
/****************************************************************************/
/* ***************************TAP for OTHER PROTOCOL **********************************/
diff --git a/ui/gtk/voip_calls.h b/ui/gtk/voip_calls.h
index 625e3801ad..f478c56aab 100644
--- a/ui/gtk/voip_calls.h
+++ b/ui/gtk/voip_calls.h
@@ -67,6 +67,15 @@ typedef enum _hash_indexes {
extern const char *voip_protocol_name[];
+typedef enum _flow_show_options
+{
+ FLOW_ALL,
+ FLOW_ONLY_INVITES
+} flow_show_options;
+
+flow_show_options VoIPcalls_get_flow_show_option(void);
+void VoIPcalls_set_flow_show_option(flow_show_options option);
+
/** defines specific SIP data */
typedef enum _sip_call_state {
diff --git a/ui/gtk/voip_calls_dlg.c b/ui/gtk/voip_calls_dlg.c
index 14ddbbc1a7..78bb0eaf21 100644
--- a/ui/gtk/voip_calls_dlg.c
+++ b/ui/gtk/voip_calls_dlg.c
@@ -312,8 +312,6 @@ voip_calls_on_select_all(GtkButton *button _U_, gpointer user_data _U_)
gtk_tree_selection_select_all(selection);
}
-
-
/* compare two list entries by packet no */
static gint
graph_analysis_sort_compare(gconstpointer a, gconstpointer b)
@@ -379,6 +377,13 @@ on_graph_bt_clicked(GtkButton *button _U_, gpointer user_data _U_)
}
/****************************************************************************/
+static void
+on_flow_bt_clicked(GtkButton *button _U_, gpointer user_data _U_)
+{
+ on_graph_bt_clicked(button,user_data);
+}
+
+/****************************************************************************/
#ifdef HAVE_LIBPORTAUDIO
static void
on_player_bt_clicked(GtkButton *button _U_, gpointer user_data _U_)
@@ -470,6 +475,8 @@ add_to_list_store(voip_calls_info_t* strinfo)
break;
default:
field[CALL_COL_COMMENTS][0]='\0';
+ if (strinfo->call_comment)
+ g_snprintf(field[CALL_COL_COMMENTS],30, "%s", strinfo->call_comment);
}
/* Acquire an iterator */
@@ -719,7 +726,7 @@ voip_calls_dlg_create(void)
bt_graph = ws_gtk_button_new_from_stock(WIRESHARK_STOCK_VOIP_FLOW);
gtk_container_add(GTK_CONTAINER(hbuttonbox), bt_graph);
gtk_widget_show(bt_graph);
- g_signal_connect(bt_graph, "clicked", G_CALLBACK(on_graph_bt_clicked), NULL);
+ g_signal_connect(bt_graph, "clicked", G_CALLBACK(on_flow_bt_clicked), NULL);
gtk_widget_set_tooltip_text(bt_graph, "Show a flow graph of the selected calls.");
#ifdef HAVE_LIBPORTAUDIO
@@ -906,6 +913,16 @@ voip_calls_init_tap(const char *dummy _U_, void* userdata _U_)
void
voip_calls_launch(GtkAction *action _U_, gpointer user_data _U_)
{
+ VoIPcalls_set_flow_show_option(FLOW_ONLY_INVITES);
+ voip_calls_init_tap("", NULL);
+}
+
+/****************************************************************************/
+/* entry point when called via the GTK menu */
+void
+voip_flows_launch(GtkAction *action _U_, gpointer user_data _U_)
+{
+ VoIPcalls_set_flow_show_option(FLOW_ALL);
voip_calls_init_tap("", NULL);
}