2 * VoIP calls summary addition for Wireshark
4 * Copyright 2004, Ericsson, Spain
5 * By Francisco Alcoba <francisco.alcoba@ericsson.com>
7 * based on h323_calls.c
8 * Copyright 2004, Iskratel, Ltd, Kranj
9 * By Miha Jemec <m.jemec@iskratel.si>
11 * H323, RTP, RTP Event, MGCP, AudioCodes (ISDN PRI and CAS), T38 and Graph Support
12 * By Alejandro Vaquero, alejandro.vaquero@verso.com
13 * Copyright 2005, Verso Technologies Inc.
15 * Wireshark - Network traffic analyzer
16 * By Gerald Combs <gerald@wireshark.org>
17 * Copyright 1998 Gerald Combs
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU General Public License
21 * as published by the Free Software Foundation; either version 2
22 * of the License, or (at your option) any later version.
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
39 #include "epan/epan_dissect.h"
40 #include "epan/packet.h"
41 #include "epan/proto_data.h"
42 #include "epan/to_str.h"
43 #include "epan/dissectors/packet-sip.h"
44 #include "epan/dissectors/packet-h225.h"
45 #include "epan/dissectors/packet-h245.h"
46 #include "epan/dissectors/packet-isup.h"
47 #include "epan/dissectors/packet-sdp.h"
48 #include "epan/dissectors/packet-mgcp.h"
49 #include "epan/dissectors/packet-mtp3.h"
50 #include "epan/dissectors/packet-actrace.h"
51 #include "epan/dissectors/packet-q931.h"
52 #include "epan/dissectors/packet-rtp.h"
53 #include "epan/dissectors/packet-rtp-events.h"
54 #include "epan/dissectors/packet-t38.h"
55 #include "epan/dissectors/packet-t30.h"
56 #include "epan/dissectors/packet-h248.h"
57 #include "epan/dissectors/packet-sccp.h"
58 #include "plugins/unistim/packet-unistim.h"
59 #include "epan/dissectors/packet-skinny.h"
60 #include "epan/dissectors/packet-iax2.h"
61 #include "epan/rtp_pt.h"
63 #include "ui/rtp_stream.h"
64 #include "ui/simple_dialog.h"
65 #include "ui/ui_util.h"
66 #include "ui/voip_calls.h"
68 #define DUMP_PTR1(p) printf("#=> %p\n",(void *)p)
69 #define DUMP_PTR2(p) printf("==> %p\n",(void *)p)
71 const char *voip_call_state_name[8]={
82 /* defines whether we can consider the call active */
83 const char *voip_protocol_name[]={
102 * Tap IDs must be unique. Since different taps need to share the
103 * same voip_calls_tapinfo_t *, make it unique by offsetting its
107 tap_id_offset_actrace_,
109 tap_id_offset_h245dg_,
114 tap_id_offset_megaco_,
119 tap_id_offset_rtp_event_,
123 tap_id_offset_skinny_,
126 tap_id_offset_unistim_,
130 #define REDRAW_ACTRACE (1 << tap_id_offset_actrace_)
131 #define REDRAW_H225 (1 << tap_id_offset_h225_)
132 #define REDRAW_H245DG (1 << tap_id_offset_h245dg_)
133 #define REDRAW_H248 (1 << tap_id_offset_h248_)
134 #define REDRAW_IAX2 (1 << tap_id_offset_iax2_)
135 #define REDRAW_ISUP (1 << tap_id_offset_isup_)
136 #define REDRAW_M3UA (1 << tap_id_offset_m3ua_)
137 #define REDRAW_MEGACO (1 << tap_id_offset_megaco_)
138 #define REDRAW_MGCP (1 << tap_id_offset_mgcp_)
139 #define REDRAW_MTP3 (1 << tap_id_offset_mtp3_)
140 #define REDRAW_Q931 (1 << tap_id_offset_q931_)
141 #define REDRAW_RTP (1 << tap_id_offset_rtp_)
142 #define REDRAW_RTP_EVENT (1 << tap_id_offset_rtp_event_)
143 #define REDRAW_SCCP (1 << tap_id_offset_sccp_)
144 #define REDRAW_SDP (1 << tap_id_offset_sdp_)
145 #define REDRAW_SIP (1 << tap_id_offset_sip_)
146 #define REDRAW_SKINNY (1 << tap_id_offset_skinny_)
147 #define REDRAW_SUA (1 << tap_id_offset_sua_)
148 #define REDRAW_T38 (1 << tap_id_offset_t38_)
149 #define REDRAW_UNISTIM (1 << tap_id_offset_unistim_)
150 #define REDRAW_VOIP (1 << tap_id_offset_voip_)
153 tap_base_to_id(voip_calls_tapinfo_t* tap_base, int offset) {
154 return GSIZE_TO_POINTER(GPOINTER_TO_SIZE(tap_base) + offset);
157 static inline voip_calls_tapinfo_t *
158 tap_id_to_base(void* tap_id, int offset) {
159 return (voip_calls_tapinfo_t *) GSIZE_TO_POINTER(GPOINTER_TO_SIZE(tap_id) - offset);
169 typedef struct _h245_labels {
172 graph_str labels[H245_MAX];
175 static void actrace_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
176 static void h225_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
177 static void h245dg_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
178 static void h248_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
179 static void iax2_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
180 static void isup_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
181 static void mgcp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
182 static void mtp3_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
183 static void q931_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
184 static void rtp_event_init_tap(voip_calls_tapinfo_t *tap_id_base);
185 static void rtp_init_tap(voip_calls_tapinfo_t *tap_id_base);
186 static void sccp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
187 static void sdp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
188 static void sip_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
189 static void skinny_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
190 static void t38_init_tap(voip_calls_tapinfo_t *tap_id_base);
191 static void unistim_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
192 static void voip_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
195 voip_calls_init_all_taps(voip_calls_tapinfo_t *tap_id_base)
197 actrace_calls_init_tap(tap_id_base);
198 h225_calls_init_tap(tap_id_base);
199 h245dg_calls_init_tap(tap_id_base);
200 h248_calls_init_tap(tap_id_base);
201 iax2_calls_init_tap(tap_id_base);
202 isup_calls_init_tap(tap_id_base);
203 mgcp_calls_init_tap(tap_id_base);
204 mtp3_calls_init_tap(tap_id_base);
205 q931_calls_init_tap(tap_id_base);
206 rtp_event_init_tap(tap_id_base);
207 rtp_init_tap(tap_id_base); /* This calls tap_reset_cb, tap_packet_cb, and tap_draw_cb */
208 sccp_calls_init_tap(tap_id_base);
209 sdp_calls_init_tap(tap_id_base);
210 sip_calls_init_tap(tap_id_base);
211 skinny_calls_init_tap(tap_id_base);
212 t38_init_tap(tap_id_base);
213 /* We don't register this tap if we don't have the unistim plugin loaded.*/
214 if (find_tap_id("unistim")) {
215 unistim_calls_init_tap(tap_id_base);
217 if (find_tap_id("voip")) {
218 voip_calls_init_tap(tap_id_base);
222 static void remove_tap_listener_actrace_calls(voip_calls_tapinfo_t *tap_id_base);
223 static void remove_tap_listener_h225_calls(voip_calls_tapinfo_t *tap_id_base);
224 static void remove_tap_listener_h245dg_calls(voip_calls_tapinfo_t *tap_id_base);
225 static void remove_tap_listener_h248_calls(voip_calls_tapinfo_t *tap_id_base);
226 static void remove_tap_listener_iax2_calls(voip_calls_tapinfo_t *tap_id_base);
227 static void remove_tap_listener_isup_calls(voip_calls_tapinfo_t *tap_id_base);
228 static void remove_tap_listener_mgcp_calls(voip_calls_tapinfo_t *tap_id_base);
229 static void remove_tap_listener_mtp3_calls(voip_calls_tapinfo_t *tap_id_base);
230 static void remove_tap_listener_q931_calls(voip_calls_tapinfo_t *tap_id_base);
231 static void remove_tap_listener_rtp(voip_calls_tapinfo_t *tap_id_base);
232 static void remove_tap_listener_rtp_event(voip_calls_tapinfo_t *tap_id_base);
233 static void remove_tap_listener_sccp_calls(voip_calls_tapinfo_t *tap_id_base);
234 static void remove_tap_listener_sdp_calls(voip_calls_tapinfo_t *tap_id_base);
235 static void remove_tap_listener_sip_calls(voip_calls_tapinfo_t *tap_id_base);
236 static void remove_tap_listener_skinny_calls(voip_calls_tapinfo_t *tap_id_base);
237 static void remove_tap_listener_t38(voip_calls_tapinfo_t *tap_id_base);
238 static void remove_tap_listener_unistim_calls(voip_calls_tapinfo_t *tap_id_base);
239 static void remove_tap_listener_voip_calls(voip_calls_tapinfo_t *tap_id_base);
241 void voip_calls_remove_all_tap_listeners(voip_calls_tapinfo_t *tap_id_base)
243 /* Remove the calls tap listener */
244 remove_tap_listener_actrace_calls(tap_id_base);
245 remove_tap_listener_h225_calls(tap_id_base);
246 remove_tap_listener_h245dg_calls(tap_id_base);
247 remove_tap_listener_h248_calls(tap_id_base);
248 remove_tap_listener_iax2_calls(tap_id_base);
249 remove_tap_listener_isup_calls(tap_id_base);
250 remove_tap_listener_mgcp_calls(tap_id_base);
251 remove_tap_listener_mtp3_calls(tap_id_base);
252 remove_tap_listener_q931_calls(tap_id_base);
253 remove_tap_listener_rtp(tap_id_base);
254 remove_tap_listener_rtp_event(tap_id_base);
255 remove_tap_listener_sccp_calls(tap_id_base);
256 remove_tap_listener_sdp_calls(tap_id_base);
257 remove_tap_listener_sip_calls(tap_id_base);
258 remove_tap_listener_skinny_calls(tap_id_base);
259 remove_tap_listener_t38(tap_id_base);
260 if (find_tap_id("unistim")) { /* The plugin may be missing */
261 remove_tap_listener_unistim_calls(tap_id_base);
263 if (find_tap_id("voip")) {
264 remove_tap_listener_voip_calls(tap_id_base);
268 /****************************************************************************/
269 /* when there is a [re]reading of packet's */
271 voip_calls_reset_all_taps(voip_calls_tapinfo_t *tapinfo)
273 voip_calls_info_t *callsinfo;
274 rtp_stream_info_t *strinfo;
277 /* VOIP_CALLS_DEBUG("reset packets: %d streams: %d", tapinfo->npackets, tapinfo->nrtp_streams); */
279 /* free the data items first */
280 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
283 callsinfo = (voip_calls_info_t *)list->data;
284 g_free(callsinfo->call_id);
285 g_free(callsinfo->from_identity);
286 g_free(callsinfo->to_identity);
287 free_address(&callsinfo->initial_speaker);
288 g_free(callsinfo->protocol_name);
289 g_free(callsinfo->call_comment);
291 if (callsinfo->free_prot_info && callsinfo->prot_info)
292 callsinfo->free_prot_info(callsinfo->prot_info);
295 list = g_list_next(list);
297 g_queue_clear(tapinfo->callsinfos);
298 /* free the SIP_HASH */
299 if(NULL!=tapinfo->callsinfo_hashtable[SIP_HASH])
300 g_hash_table_remove_all (tapinfo->callsinfo_hashtable[SIP_HASH]);
302 /* free the strinfo data items first */
303 list = g_list_first(tapinfo->rtp_stream_list);
306 strinfo = (rtp_stream_info_t *)list->data;
307 wmem_free(NULL, strinfo->payload_type_name);
308 list = g_list_next(list);
310 g_list_free(tapinfo->rtp_stream_list);
311 tapinfo->rtp_stream_list = NULL;
313 if (tapinfo->h245_labels) {
314 memset(tapinfo->h245_labels, 0, sizeof(h245_labels_t));
318 tapinfo->start_packets = 0;
319 tapinfo->completed_calls = 0;
320 tapinfo->rejected_calls = 0;
325 /****************************************************************************/
326 /* Add a new item into the graph */
328 add_to_graph(voip_calls_tapinfo_t *tapinfo, packet_info *pinfo, epan_dissect_t *edt, const gchar *frame_label, const gchar *comment, guint16 call_num, address *src_addr, address *dst_addr, guint16 line_style)
330 seq_analysis_item_t *gai;
331 gchar time_str[COL_MAX_LEN];
333 if (!tapinfo->graph_analysis) {
337 gai = (seq_analysis_item_t *)g_malloc0(sizeof(seq_analysis_item_t));
338 gai->frame_number = pinfo->num;
339 copy_address(&(gai->src_addr),src_addr);
340 copy_address(&(gai->dst_addr),dst_addr);
342 gai->port_src=pinfo->srcport;
343 gai->port_dst=pinfo->destport;
344 gai->protocol = g_strdup(port_type_to_str(pinfo->ptype));
346 if (frame_label != NULL)
347 gai->frame_label = g_strdup(frame_label);
349 gai->frame_label = g_strdup("");
352 gai->comment = g_strdup(comment);
354 gai->comment = g_strdup("");
356 gai->conv_num=call_num;
357 gai->line_style=line_style;
358 set_fd_time(edt->session, pinfo->fd, time_str);
359 gai->time_str = g_strdup(time_str);
362 g_queue_push_tail(tapinfo->graph_analysis->items, gai);
363 g_hash_table_insert(tapinfo->graph_analysis->ht, &gai->frame_number, gai);
366 /****************************************************************************/
367 /* Append str to frame_label and comment in a graph item */
368 /* return 0 if the frame_num is not in the graph list */
369 static int append_to_frame_graph(voip_calls_tapinfo_t *tapinfo, guint32 frame_num, const gchar *new_frame_label, const gchar *new_comment)
371 seq_analysis_item_t *gai=NULL;
372 gchar *frame_label = NULL;
373 gchar *comment = NULL;
375 if(tapinfo->graph_analysis && NULL!=tapinfo->graph_analysis->ht)
376 gai=(seq_analysis_item_t *)g_hash_table_lookup(tapinfo->graph_analysis->ht, &frame_num);
378 frame_label = gai->frame_label;
379 comment = gai->comment;
381 if (new_frame_label != NULL) {
382 gai->frame_label = g_strdup_printf("%s %s", frame_label, new_frame_label);
386 if (new_comment != NULL) {
387 gai->comment = g_strdup_printf("%s %s", comment, new_comment);
395 /****************************************************************************/
396 /* Change the frame_label and comment in a graph item if not NULL*/
397 /* return 0 if the frame_num is not in the graph list */
398 static int change_frame_graph(voip_calls_tapinfo_t *tapinfo, guint32 frame_num, const gchar *new_frame_label, const gchar *new_comment)
400 seq_analysis_item_t *gai=NULL;
401 gchar *frame_label = NULL;
402 gchar *comment = NULL;
404 if(tapinfo->graph_analysis && NULL!=tapinfo->graph_analysis->ht)
405 gai=(seq_analysis_item_t *)g_hash_table_lookup(tapinfo->graph_analysis->ht, &frame_num);
407 frame_label = gai->frame_label;
408 comment = gai->comment;
410 if (new_frame_label != NULL) {
411 gai->frame_label = g_strdup(new_frame_label);
415 if (new_comment != NULL) {
416 gai->comment = g_strdup(new_comment);
424 /****************************************************************************/
425 /* Change all the graph items with call_num to new_call_num */
426 static guint change_call_num_graph(voip_calls_tapinfo_t *tapinfo, guint16 call_num, guint16 new_call_num)
428 seq_analysis_item_t *gai;
433 if(tapinfo->graph_analysis){
434 list = g_queue_peek_nth_link(tapinfo->graph_analysis->items, 0);
437 gai = (seq_analysis_item_t *)list->data;
438 if (gai->conv_num == call_num) {
439 gai->conv_num = new_call_num;
442 list = g_list_next(list);
445 return items_changed;
448 /****************************************************************************/
449 /* Insert the item in the graph list */
450 static void insert_to_graph_t38(voip_calls_tapinfo_t *tapinfo, packet_info *pinfo, epan_dissect_t *edt, const gchar *frame_label, const gchar *comment, guint16 call_num, address *src_addr, address *dst_addr, guint16 line_style, guint32 frame_num)
452 seq_analysis_item_t *gai, *new_gai;
456 gchar time_str[COL_MAX_LEN];
458 new_gai = (seq_analysis_item_t *)g_malloc0(sizeof(seq_analysis_item_t));
459 new_gai->frame_number = frame_num;
460 copy_address(&(new_gai->src_addr),src_addr);
461 copy_address(&(new_gai->dst_addr),dst_addr);
463 new_gai->port_src=pinfo->srcport;
464 new_gai->port_dst=pinfo->destport;
465 new_gai->protocol = g_strdup(port_type_to_str(pinfo->ptype));
466 if (frame_label != NULL)
467 new_gai->frame_label = g_strdup(frame_label);
469 new_gai->frame_label = g_strdup("");
472 new_gai->comment = g_strdup(comment);
474 new_gai->comment = g_strdup("");
475 new_gai->conv_num=call_num;
476 new_gai->line_style=line_style;
477 set_fd_time(edt->session, pinfo->fd, time_str);
478 new_gai->time_str = g_strdup(time_str);
479 new_gai->display=FALSE;
483 if(tapinfo->graph_analysis){
484 list = g_queue_peek_nth_link(tapinfo->graph_analysis->items, 0);
487 gai = (seq_analysis_item_t *)list->data;
488 if (gai->frame_number > frame_num) {
489 g_queue_insert_before(tapinfo->graph_analysis->items, list, new_gai);
490 g_hash_table_insert(tapinfo->graph_analysis->ht, &new_gai->frame_number, new_gai);
494 list = g_list_next(list);
499 g_queue_push_tail(tapinfo->graph_analysis->items, new_gai);
500 g_hash_table_insert(tapinfo->graph_analysis->ht, &new_gai->frame_number, new_gai);
505 /****************************************************************************/
506 /* ***************************TAP for RTP Events*****************************/
507 /****************************************************************************/
509 /*static guint32 rtp_evt_setup_frame_num = 0;*/
511 /****************************************************************************/
512 /* whenever a rtp event packet is seen by the tap listener */
514 rtp_event_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt _U_, const void *rtp_event_info)
516 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_event_);
517 const struct _rtp_event_info *pi = (const struct _rtp_event_info *)rtp_event_info;
519 /* do not consider RTP events packets without a setup frame */
520 if (pi->info_setup_frame_num == 0) {
524 tapinfo->rtp_evt_frame_num = pinfo->num;
525 tapinfo->rtp_evt = pi->info_rtp_evt;
526 tapinfo->rtp_evt_end = pi->info_end;
531 /****************************************************************************/
533 rtp_event_init_tap(voip_calls_tapinfo_t *tap_id_base)
535 GString *error_string;
537 error_string = register_tap_listener("rtpevent", tap_base_to_id(tap_id_base, tap_id_offset_rtp_event_),
545 if (error_string != NULL) {
546 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
547 "%s", error_string->str);
548 g_string_free(error_string, TRUE);
552 /****************************************************************************/
555 remove_tap_listener_rtp_event(voip_calls_tapinfo_t *tap_id_base)
557 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_rtp_event_));
560 /****************************************************************************/
561 /* ***************************TAP for RTP **********************************/
562 /****************************************************************************/
564 /****************************************************************************/
565 /* when there is a [re]reading of RTP packets */
567 rtp_reset(void *tap_offset_ptr)
569 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_);
572 /* free the data items first */
573 list = g_list_first(tapinfo->rtp_stream_list);
577 list = g_list_next(list);
579 g_list_free(tapinfo->rtp_stream_list);
580 tapinfo->rtp_stream_list = NULL;
581 tapinfo->nrtp_streams = 0;
583 if (tapinfo->tap_reset) {
584 tapinfo->tap_reset(tapinfo);
590 /****************************************************************************/
591 /* whenever a RTP packet is seen by the tap listener */
593 rtp_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, void const *rtp_info_ptr)
595 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_);
596 rtp_stream_info_t *tmp_listinfo;
597 rtp_stream_info_t *strinfo = NULL;
599 struct _rtp_conversation_info *p_conv_data = NULL;
601 const struct _rtp_info *rtp_info = (const struct _rtp_info *)rtp_info_ptr;
603 /* do not consider RTP packets without a setup frame */
604 if (rtp_info->info_setup_frame_num == 0) {
608 if (tapinfo->tap_packet) {
609 tapinfo->tap_packet(tapinfo, pinfo, edt, rtp_info_ptr);
612 /* check whether we already have a RTP stream with this setup frame and ssrc in the list */
613 list = g_list_first(tapinfo->rtp_stream_list);
616 tmp_listinfo=(rtp_stream_info_t *)list->data;
617 if ( (tmp_listinfo->setup_frame_number == rtp_info->info_setup_frame_num)
618 && (tmp_listinfo->ssrc == rtp_info->info_sync_src) && (tmp_listinfo->end_stream == FALSE)) {
619 /* if the payload type has changed, we mark the stream as finished to create a new one
620 this is to show multiple payload changes in the Graph for example for DTMF RFC2833 */
621 if ( tmp_listinfo->payload_type != rtp_info->info_payload_type ) {
622 tmp_listinfo->end_stream = TRUE;
624 strinfo = (rtp_stream_info_t*)(list->data);
628 list = g_list_next(list);
631 /* if this is a duplicated RTP Event End, just return */
632 if ((tapinfo->rtp_evt_frame_num == pinfo->num) && !strinfo && (tapinfo->rtp_evt_end == TRUE)) {
636 /* not in the list? then create a new entry */
638 strinfo = (rtp_stream_info_t *)g_malloc0(sizeof(rtp_stream_info_t));
639 copy_address(&(strinfo->src_addr), &(pinfo->src));
640 strinfo->src_port = pinfo->srcport;
641 copy_address(&(strinfo->dest_addr), &(pinfo->dst));
642 strinfo->dest_port = pinfo->destport;
643 strinfo->ssrc = rtp_info->info_sync_src;
644 strinfo->payload_type = rtp_info->info_payload_type;
645 strinfo->is_srtp = rtp_info->info_is_srtp;
646 /* if it is dynamic payload, let use the conv data to see if it is defined */
647 if ( (strinfo->payload_type >= PT_UNDF_96) && (strinfo->payload_type <= PT_UNDF_127) ) {
648 /* Use existing packet info if available */
649 p_conv_data = (struct _rtp_conversation_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_get_id_by_filter_name("rtp"), 0);
650 if (p_conv_data && p_conv_data->rtp_dyn_payload) {
651 const gchar *encoding_name = rtp_dyn_payload_get_name(p_conv_data->rtp_dyn_payload, strinfo->payload_type);
653 strinfo->payload_type_name = wmem_strdup(NULL, encoding_name);
657 if (!strinfo->payload_type_name) strinfo->payload_type_name = (gchar*)val_to_str_ext_wmem(NULL, strinfo->payload_type, &rtp_payload_type_short_vals_ext, "%u");
658 strinfo->start_fd = pinfo->fd;
659 strinfo->start_rel_time = pinfo->rel_ts;
660 strinfo->setup_frame_number = rtp_info->info_setup_frame_num;
661 strinfo->call_num = -1;
662 strinfo->rtp_event = -1;
663 tapinfo->rtp_stream_list = g_list_prepend(tapinfo->rtp_stream_list, strinfo);
666 /* Add the info to the existing RTP stream */
667 strinfo->packet_count++;
668 strinfo->stop_fd = pinfo->fd;
670 /* process RTP Event */
671 if (tapinfo->rtp_evt_frame_num == pinfo->num) {
672 strinfo->rtp_event = tapinfo->rtp_evt;
673 if (tapinfo->rtp_evt_end == TRUE) {
674 strinfo->end_stream = TRUE;
678 tapinfo->redraw |= REDRAW_RTP;
683 /****************************************************************************/
684 /* whenever a redraw in the RTP tap listener */
686 rtp_draw(void *tap_offset_ptr)
688 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_);
689 GList *rtp_streams_list;
690 rtp_stream_info_t *rtp_listinfo;
691 /* GList *voip_calls_graph_list; */
692 seq_analysis_item_t *gai = NULL;
693 seq_analysis_item_t *new_gai;
696 gchar time_str[COL_MAX_LEN];
698 /* add each rtp stream to the graph */
699 rtp_streams_list = g_list_first(tapinfo->rtp_stream_list);
700 while (rtp_streams_list)
702 rtp_listinfo = (rtp_stream_info_t *)rtp_streams_list->data;
704 /* using the setup frame number of the RTP stream, we get the call number that it belongs to*/
705 /* voip_calls_graph_list = g_list_first(tapinfo->graph_analysis->list); */
706 if(tapinfo->graph_analysis){
707 gai = (seq_analysis_item_t *)g_hash_table_lookup(tapinfo->graph_analysis->ht, &rtp_listinfo->setup_frame_number);
710 const char *comment_fmt = "%s, %u packets. Duration: %u.%03us SSRC: 0x%X";
711 /* Found the setup frame*/
712 conv_num = gai->conv_num;
713 /* if RTP was already in the Graph, just update the comment information */
714 gai = (seq_analysis_item_t *)g_hash_table_lookup(tapinfo->graph_analysis->ht, &rtp_listinfo->start_fd->num);
716 duration = (guint32)(nstime_to_msec(&rtp_listinfo->stop_rel_time) - nstime_to_msec(&rtp_listinfo->start_rel_time));
717 g_free(gai->comment);
718 gai->comment = g_strdup_printf(comment_fmt,
719 (rtp_listinfo->is_srtp)?"SRTP":"RTP", rtp_listinfo->packet_count,
720 duration/1000,(duration%1000), rtp_listinfo->ssrc);
722 new_gai = (seq_analysis_item_t *)g_malloc0(sizeof(seq_analysis_item_t));
723 new_gai->frame_number = rtp_listinfo->start_fd->num;
724 copy_address(&(new_gai->src_addr),&(rtp_listinfo->src_addr));
725 copy_address(&(new_gai->dst_addr),&(rtp_listinfo->dest_addr));
726 new_gai->port_src = rtp_listinfo->src_port;
727 new_gai->port_dst = rtp_listinfo->dest_port;
728 duration = (guint32)(nstime_to_msec(&rtp_listinfo->stop_rel_time) - nstime_to_msec(&rtp_listinfo->start_rel_time));
729 new_gai->frame_label = g_strdup_printf("%s (%s) %s",
730 (rtp_listinfo->is_srtp)?"SRTP":"RTP",
731 rtp_listinfo->payload_type_name,
732 (rtp_listinfo->rtp_event == -1)?
733 "":val_to_str_ext_const(rtp_listinfo->rtp_event, &rtp_event_type_values_ext, "Unknown RTP Event"));
734 new_gai->comment = g_strdup_printf(comment_fmt,
735 (rtp_listinfo->is_srtp)?"SRTP":"RTP", rtp_listinfo->packet_count,
736 duration/1000,(duration%1000), rtp_listinfo->ssrc);
737 new_gai->conv_num = conv_num;
738 set_fd_time(tapinfo->session, rtp_listinfo->start_fd, time_str);
739 new_gai->time_str = g_strdup(time_str);
740 new_gai->display=FALSE;
741 new_gai->line_style = 2; /* the arrow line will be 2 pixels width */
742 g_queue_push_tail(tapinfo->graph_analysis->items, new_gai);
743 g_hash_table_insert(tapinfo->graph_analysis->ht, &rtp_listinfo->start_fd, new_gai);
746 rtp_streams_list = g_list_next(rtp_streams_list);
747 } /* while (rtp_streams_list) */
749 if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_RTP)) {
750 tapinfo->tap_draw(tapinfo);
751 tapinfo->redraw &= ~REDRAW_RTP;
756 rtp_packet_draw(void *tap_offset_ptr)
758 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_);
759 GList *rtp_streams_list;
760 rtp_stream_info_t *rtp_listinfo;
761 GList *voip_calls_graph_list;
763 seq_analysis_item_t *gai;
764 seq_analysis_item_t *new_gai;
767 gchar time_str[COL_MAX_LEN];
769 /* add each rtp stream to the graph */
770 rtp_streams_list = g_list_first(tapinfo->stream_list);
771 while (rtp_streams_list)
773 rtp_listinfo = rtp_streams_list->data;
775 /* using the setup frame number of the RTP stream, we get the call number that it belongs to*/
776 voip_calls_graph_list = g_list_first(tapinfo->graph_analysis->list);
777 while (voip_calls_graph_list)
779 gai = voip_calls_graph_list->data;
780 conv_num = gai->conv_num;
781 /* if we get the setup frame number, then get the time position to graph the RTP arrow */
782 if (rtp_listinfo->setup_frame_number == gai->frame_number) {
783 /* look again from the beginning because there are cases where the Setup frame is after the RTP */
784 voip_calls_graph_list = g_list_first(tapinfo->graph_analysis->list);
786 while(voip_calls_graph_list) {
787 gai = voip_calls_graph_list->data;
788 /* if RTP was already in the Graph, just update the comment information */
789 if (rtp_listinfo->start_fd->num == gai->frame_number) {
790 duration = (guint32)(nstime_to_msec(&rtp_listinfo->stop_fd->rel_ts) - nstime_to_msec(&rtp_listinfo->start_fd->rel_ts));
791 g_free(gai->comment);
792 gai->comment = g_strdup_printf("%s Num packets:%u Duration:%u.%03us SSRC:0x%X",
793 (rtp_listinfo->is_srtp)?"SRTP":"RTP", rtp_listinfo->npackets,
794 duration/1000,(duration%1000), rtp_listinfo->ssrc);
798 /* we increment the list here to be able to check if it is the last item in this calls, which means the RTP is after so we have to draw it */
799 voip_calls_graph_list = g_list_next(voip_calls_graph_list);
800 if (!voip_calls_graph_list) item++;
802 /* add the RTP item to the graph if was not there*/
803 if (rtp_listinfo->start_fd->num<gai->frame_number || !voip_calls_graph_list) {
804 new_gai = g_malloc0(sizeof(seq_analysis_item_t));
805 new_gai->frame_number = rtp_listinfo->start_fd->num;
806 copy_address(&(new_gai->src_addr),&(rtp_listinfo->src_addr));
807 copy_address(&(new_gai->dst_addr),&(rtp_listinfo->dest_addr));
808 new_gai->port_src = rtp_listinfo->src_port;
809 new_gai->port_dst = rtp_listinfo->dest_port;
810 new_gai->protocol = g_strdup(port_type_to_str(pinfo->ptype));
811 duration = (guint32)(nstime_to_msec(&rtp_listinfo->stop_fd->rel_ts) - nstime_to_msec(&rtp_listinfo->start_fd->rel_ts));
812 new_gai->frame_label = g_strdup_printf("%s (%s) %s",
813 (rtp_listinfo->is_srtp)?"SRTP":"RTP",
814 rtp_listinfo->payload_type_str,
815 (rtp_listinfo->rtp_event == -1)?
816 "":val_to_str_ext_const(rtp_listinfo->rtp_event, &rtp_event_type_values_ext, "Unknown RTP Event"));
817 new_gai->comment = g_strdup_printf("%s Num packets:%u Duration:%u.%03us SSRC:0x%X",
818 (rtp_listinfo->is_srtp)?"SRTP":"RTP", rtp_listinfo->npackets,
819 duration/1000,(duration%1000), rtp_listinfo->ssrc);
820 new_gai->conv_num = conv_num;
821 set_fd_time(cfile.epan, rtp_listinfo->start_fd, time_str);
822 new_gai->time_str = g_strdup(time_str);
823 new_gai->display=FALSE;
824 new_gai->line_style = 2; /* the arrow line will be 2 pixels width */
825 tapinfo->graph_analysis->list = g_list_insert(tapinfo->graph_analysis->list, new_gai, item);
828 if (voip_calls_graph_list) item++;
832 voip_calls_graph_list = g_list_next(voip_calls_graph_list);
834 rtp_streams_list = g_list_next(rtp_streams_list);
839 /****************************************************************************/
841 rtp_init_tap(voip_calls_tapinfo_t *tap_id_base)
843 GString *error_string;
845 error_string = register_tap_listener("rtp", tap_base_to_id(tap_id_base, tap_id_offset_rtp_), NULL,
851 if (error_string != NULL) {
852 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
853 "%s", error_string->str);
854 g_string_free(error_string, TRUE);
858 /****************************************************************************/
860 remove_tap_listener_rtp(voip_calls_tapinfo_t *tap_id_base)
862 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_rtp_));
865 /****************************************************************************/
866 /******************************TAP for T38 **********************************/
867 /****************************************************************************/
869 /****************************************************************************/
870 /* whenever a T38 packet is seen by the tap listener */
872 t38_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *t38_info_ptr)
874 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_t38_);
876 voip_calls_info_t *callsinfo = NULL;
877 voip_calls_info_t *tmp_listinfo;
878 GList *voip_calls_graph_list = NULL;
880 gchar *frame_label = NULL;
881 gchar *comment = NULL;
882 seq_analysis_item_t *tmp_gai, *gai = NULL;
883 gchar *tmp_str1, *tmp_str2;
884 guint16 line_style = 2;
888 const t38_packet_info *t38_info = (const t38_packet_info *)t38_info_ptr;
890 if (t38_info->setup_frame_number != 0) {
891 /* using the setup frame number of the T38 packet, we get the call number that it belongs */
892 if(tapinfo->graph_analysis){
893 voip_calls_graph_list = g_queue_peek_nth_link(tapinfo->graph_analysis->items, 0);
895 while (voip_calls_graph_list)
897 tmp_gai = (seq_analysis_item_t *)voip_calls_graph_list->data;
898 if (t38_info->setup_frame_number == tmp_gai->frame_number) {
902 voip_calls_graph_list = g_list_next(voip_calls_graph_list);
904 if (gai) conv_num = (int) gai->conv_num;
907 /* if setup_frame_number in the t38 packet is 0, it means it was not set using an SDP or H245 sesion, which means we don't
908 * have the associated Voip calls. It probably means the the packet was decoded using the default t38 port, or using "Decode as.."
909 * in this case we create a "voip" call that only have t38 media (no signaling)
910 * OR if we have not found the Setup message in the graph.
912 if ( (t38_info->setup_frame_number == 0) || (gai == NULL) ) {
913 /* check whether we already have a call with these parameters in the list */
914 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
917 tmp_listinfo=(voip_calls_info_t *)list->data;
918 if (tmp_listinfo->protocol == MEDIA_T38) {
919 callsinfo = (voip_calls_info_t*)(list->data);
922 list = g_list_next (list);
925 /* not in the list? then create a new entry */
926 if (callsinfo==NULL) {
927 callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
928 callsinfo->call_active_state = VOIP_ACTIVE;
929 callsinfo->call_state = VOIP_UNKNOWN;
930 callsinfo->from_identity=g_strdup("T38 Media only");
931 callsinfo->to_identity=g_strdup("T38 Media only");
932 copy_address(&(callsinfo->initial_speaker),&(pinfo->src));
933 callsinfo->selected=FALSE;
934 callsinfo->start_fd = pinfo->fd;
935 callsinfo->start_rel_ts = pinfo->rel_ts;
936 callsinfo->protocol=MEDIA_T38;
937 callsinfo->prot_info=NULL;
938 callsinfo->free_prot_info = NULL;
939 callsinfo->npackets = 0;
940 callsinfo->call_num = tapinfo->ncalls++;
941 g_queue_push_tail(tapinfo->callsinfos, callsinfo);
943 callsinfo->stop_fd = pinfo->fd;
944 callsinfo->stop_rel_ts = pinfo->rel_ts;
945 ++(callsinfo->npackets);
946 /* increment the packets counter of all calls */
947 ++(tapinfo->npackets);
949 conv_num = (int) callsinfo->call_num;
952 /* at this point we should have found the call num for this t38 packets belong */
953 if (conv_num == -1) {
957 /* add the item to the graph list */
958 if (t38_info->type_msg == 0) { /* 0=t30-indicator */
959 tmp_str1 = val_to_str_wmem(NULL, t38_info->t30ind_value, t38_T30_indicator_vals, "Ukn (0x%02X)");
960 frame_label = g_strdup(tmp_str1);
961 comment = g_strdup_printf("t38:t30 Ind:%s", tmp_str1);
962 wmem_free(NULL, tmp_str1);
964 } else if (t38_info->type_msg == 1) { /* 1=data */
965 switch(t38_info->Data_Field_field_type_value) {
966 case 0: /* hdlc-data */
968 case 2: /* hdlc-fcs-OK */
969 case 4: /* hdlc-fcs-OK-sig-end */
970 tmp_str1 = val_to_str_ext_wmem(NULL, t38_info->t30_Facsimile_Control & 0x7F,
971 &t30_facsimile_control_field_vals_short_ext,
973 frame_label = g_strdup_printf("%s %s",
976 wmem_free(NULL, tmp_str1);
978 tmp_str1 = val_to_str_ext_wmem(NULL, t38_info->t30_Facsimile_Control & 0x7F,
979 &t30_facsimile_control_field_vals_ext,
981 tmp_str2 = val_to_str_wmem(NULL, t38_info->data_value,
984 comment = g_strdup_printf("t38:%s:HDLC:%s", tmp_str2, tmp_str1);
985 wmem_free(NULL, tmp_str1);
986 wmem_free(NULL, tmp_str2);
988 case 3: /* hdlc-fcs-BAD */
989 case 5: /* hdlc-fcs-BAD-sig-end */
990 frame_label = g_strdup(t38_info->Data_Field_field_type_value == 3 ? "fcs-BAD" : "fcs-BAD-sig-end");
991 tmp_str1 = val_to_str_wmem(NULL, t38_info->data_value, t38_T30_data_vals, "Ukn (0x%02X)");
992 comment = g_strdup_printf("WARNING: received t38:%s:HDLC:%s",
994 t38_info->Data_Field_field_type_value == 3 ? "fcs-BAD" : "fcs-BAD-sig-end");
995 wmem_free(NULL, tmp_str1);
997 case 7: /* t4-non-ecm-sig-end */
998 duration = nstime_to_sec(&pinfo->rel_ts) - t38_info->time_first_t4_data;
999 tmp_str1 = val_to_str_wmem(NULL, t38_info->data_value, t38_T30_data_vals, "Ukn (0x%02X)");
1000 frame_label = g_strdup_printf("t4-non-ecm-data:%s", tmp_str1);
1001 comment = g_strdup_printf("t38:t4-non-ecm-data:%s Duration: %.2fs %s",
1002 tmp_str1, duration, t38_info->desc_comment );
1003 insert_to_graph_t38(tapinfo, pinfo, edt, frame_label, comment,
1004 (guint16)conv_num, &(pinfo->src), &(pinfo->dst),
1005 line_style, t38_info->frame_num_first_t4_data);
1006 wmem_free(NULL, tmp_str1);
1011 if (frame_label && !(t38_info->Data_Field_field_type_value == 7 && t38_info->type_msg == 1)) {
1012 add_to_graph(tapinfo, pinfo, edt, frame_label, comment, (guint16)conv_num, &(pinfo->src), &(pinfo->dst), line_style);
1016 g_free(frame_label);
1018 tapinfo->redraw |= REDRAW_T38;
1020 return TRUE; /* refresh output */
1023 /****************************************************************************/
1025 t38_draw(void *tap_offset_ptr)
1027 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_t38_);
1029 if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_T38)) {
1030 tapinfo->tap_draw(tapinfo);
1031 tapinfo->redraw &= ~REDRAW_T38;
1035 /****************************************************************************/
1037 t38_init_tap(voip_calls_tapinfo_t *tap_id_base)
1039 GString *error_string;
1041 error_string = register_tap_listener("t38", tap_base_to_id(tap_id_base, tap_id_offset_t38_), NULL,
1047 if (error_string != NULL) {
1048 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1049 "%s", error_string->str);
1050 g_string_free(error_string, TRUE);
1054 /****************************************************************************/
1056 remove_tap_listener_t38(voip_calls_tapinfo_t *tap_id_base)
1058 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_t38_));
1062 /****************************************************************************/
1063 /* ***************************TAP for SIP **********************************/
1064 /****************************************************************************/
1067 free_sip_info(gpointer p) {
1068 sip_calls_info_t *si = (sip_calls_info_t *)p;
1070 g_free(si->call_identifier);
1074 /****************************************************************************/
1075 /* whenever a SIP packet is seen by the tap listener */
1077 sip_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt , const void *SIPinfo)
1079 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sip_);
1080 /* we just take note of the ISUP data here; when we receive the MTP3 part everything will
1081 be compared with existing calls */
1083 voip_calls_info_t *callsinfo = NULL;
1084 sip_calls_info_t *tmp_sipinfo = NULL;
1085 address tmp_src, tmp_dst;
1086 gchar *frame_label = NULL;
1087 gchar *comment = NULL;
1088 gchar *old_comment = NULL;
1091 const sip_info_value_t *pi = (const sip_info_value_t *)SIPinfo;
1093 tapinfo->sip_frame_num = pinfo->num;
1095 /* do not consider packets without call_id */
1096 if (pi->tap_call_id ==NULL) {
1099 key=pi->tap_call_id;
1100 /* init the hash table */
1101 if(NULL==tapinfo->callsinfo_hashtable[SIP_HASH]) {
1102 /* TODO: check how efficient g_str_hash is for sip call ids */
1103 tapinfo->callsinfo_hashtable[SIP_HASH]=g_hash_table_new_full(g_str_hash,
1105 NULL, /* key_destroy_func */
1106 NULL);/* value_destroy_func */
1108 /* search the call information in the SIP_HASH */
1109 callsinfo = (voip_calls_info_t *)g_hash_table_lookup(tapinfo->callsinfo_hashtable[SIP_HASH], key);
1111 /* Create a new flow entry if the message is INVITE in case of FLOW_ONLY_INVITES,
1112 Create a new flow entry for all messages which have a method in case of FLOW_ALL.
1113 Flows for REGISTER, OPTIONS, MESSAGE and other SIP methods can be seen. */
1115 if ((callsinfo==NULL) && (pi->request_method!=NULL)) {
1117 /* check VoIPcalls_get_flow_show_option() == FLOW_ALL or FLOW_ONLY_INVITES */
1119 if (tapinfo->fs_option == FLOW_ALL ||
1120 (tapinfo->fs_option == FLOW_ONLY_INVITES &&
1121 strcmp(pi->request_method,"INVITE")==0)) {
1122 callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
1123 callsinfo->call_active_state = VOIP_ACTIVE;
1124 callsinfo->call_state = VOIP_CALL_SETUP;
1125 callsinfo->from_identity=g_strdup(pi->tap_from_addr);
1126 callsinfo->to_identity=g_strdup(pi->tap_to_addr);
1127 copy_address(&(callsinfo->initial_speaker),&(pinfo->src));
1128 callsinfo->selected=FALSE;
1129 callsinfo->start_fd=pinfo->fd;
1130 callsinfo->start_rel_ts=pinfo->rel_ts;
1131 callsinfo->protocol=VOIP_SIP;
1132 callsinfo->prot_info=g_malloc(sizeof(sip_calls_info_t));
1133 callsinfo->free_prot_info = free_sip_info;
1134 callsinfo->call_id = g_strdup(pi->tap_call_id);
1135 tmp_sipinfo = (sip_calls_info_t *)callsinfo->prot_info;
1136 tmp_sipinfo->call_identifier = g_strdup(pi->tap_call_id);
1137 tmp_sipinfo->sip_state = SIP_INVITE_SENT;
1138 tmp_sipinfo->invite_cseq = pi->tap_cseq_number;
1139 callsinfo->npackets = 0;
1140 callsinfo->call_num = tapinfo->ncalls++;
1142 /* show method in comment in conversation list dialog, user can discern different conversation types */
1143 callsinfo->call_comment=g_strdup(pi->request_method);
1145 g_queue_push_tail(tapinfo->callsinfos, callsinfo);
1146 /* insert the call information in the SIP_HASH */
1147 g_hash_table_insert(tapinfo->callsinfo_hashtable[SIP_HASH],
1148 tmp_sipinfo->call_identifier, callsinfo);
1152 if (callsinfo != NULL) {
1153 tmp_sipinfo = (sip_calls_info_t *)callsinfo->prot_info;
1155 /* let's analyze the call state */
1157 copy_address(&(tmp_src), &(pinfo->src));
1158 copy_address(&(tmp_dst), &(pinfo->dst));
1160 if (pi->request_method == NULL) {
1161 frame_label = g_strdup_printf("%u %s", pi->response_code, pi->reason_phrase );
1162 comment = g_strdup_printf("SIP Status %u %s", pi->response_code, pi->reason_phrase );
1164 if ((tmp_sipinfo && pi->tap_cseq_number == tmp_sipinfo->invite_cseq)&&(addresses_equal(&tmp_dst,&(callsinfo->initial_speaker)))) {
1165 if ((pi->response_code > 199) && (pi->response_code<300) && (tmp_sipinfo->sip_state == SIP_INVITE_SENT)) {
1166 tmp_sipinfo->sip_state = SIP_200_REC;
1168 else if ((pi->response_code>299)&&(tmp_sipinfo->sip_state == SIP_INVITE_SENT)) {
1169 callsinfo->call_state = VOIP_REJECTED;
1170 tapinfo->rejected_calls++;
1173 /* UPDATE comment in conversation list dialog with response code and reason.
1174 Multiple code(+reason) may be appended, so skip over intermediate codes (100 trying, 183 ringing, e.t.c.)
1175 TODO: is useful but not perfect, what is appended is truncated when displayed in dialog window */
1176 if (pi->response_code >= 200) {
1177 old_comment = callsinfo->call_comment;
1178 callsinfo->call_comment=g_strdup_printf("%s %u",
1179 callsinfo->call_comment,
1180 pi->response_code/*, pi->reason_phrase*/);
1182 g_free(old_comment);
1189 frame_label = g_strdup(pi->request_method);
1191 if ((strcmp(pi->request_method,"INVITE")==0)&&(addresses_equal(&tmp_src,&(callsinfo->initial_speaker)))) {
1192 tmp_sipinfo->invite_cseq = pi->tap_cseq_number;
1193 callsinfo->call_state = VOIP_CALL_SETUP;
1194 /* TODO: sometimes truncated when displayed in dialog window */
1195 comment = g_strdup_printf("SIP INVITE From: %s To:%s Call-ID:%s CSeq:%d",
1196 callsinfo->from_identity, callsinfo->to_identity,
1197 callsinfo->call_id, pi->tap_cseq_number);
1199 else if ((strcmp(pi->request_method,"ACK")==0)&&(pi->tap_cseq_number == tmp_sipinfo->invite_cseq)
1200 &&(addresses_equal(&tmp_src,&(callsinfo->initial_speaker)))&&(tmp_sipinfo->sip_state==SIP_200_REC)
1201 &&(callsinfo->call_state == VOIP_CALL_SETUP)) {
1202 callsinfo->call_state = VOIP_IN_CALL;
1203 comment = g_strdup_printf("SIP Request INVITE ACK 200 CSeq:%d", pi->tap_cseq_number);
1205 else if (strcmp(pi->request_method,"BYE")==0) {
1206 callsinfo->call_state = VOIP_COMPLETED;
1207 tapinfo->completed_calls++;
1208 comment = g_strdup_printf("SIP Request BYE CSeq:%d", pi->tap_cseq_number);
1210 else if ((strcmp(pi->request_method,"CANCEL")==0)&&(pi->tap_cseq_number == tmp_sipinfo->invite_cseq)
1211 &&(addresses_equal(&tmp_src,&(callsinfo->initial_speaker)))&&(callsinfo->call_state==VOIP_CALL_SETUP)) {
1212 callsinfo->call_state = VOIP_CANCELLED;
1213 tmp_sipinfo->sip_state = SIP_CANCEL_SENT;
1214 comment = g_strdup_printf("SIP Request CANCEL CSeq:%d", pi->tap_cseq_number);
1216 /* comment = g_strdup_printf("SIP %s", pi->request_method); */
1217 comment = g_strdup_printf("SIP %s From: %s To:%s CSeq:%d",
1219 callsinfo->from_identity,
1220 callsinfo->to_identity, pi->tap_cseq_number);
1224 callsinfo->stop_fd = pinfo->fd;
1225 callsinfo->stop_rel_ts = pinfo->rel_ts;
1226 ++(callsinfo->npackets);
1227 /* increment the packets counter of all calls */
1228 ++(tapinfo->npackets);
1230 /* add to the graph */
1231 add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
1233 g_free(frame_label);
1234 free_address(&tmp_src);
1235 free_address(&tmp_dst);
1237 /* add SDP info if apply */
1238 if ( (tapinfo->sdp_summary != NULL) && (tapinfo->sdp_frame_num == pinfo->num) ) {
1239 append_to_frame_graph(tapinfo, pinfo->num, tapinfo->sdp_summary, NULL);
1240 g_free(tapinfo->sdp_summary);
1241 tapinfo->sdp_summary = NULL;
1246 tapinfo->redraw |= REDRAW_SIP;
1248 return TRUE; /* refresh output */
1251 /****************************************************************************/
1253 sip_calls_draw(void *tap_offset_ptr)
1255 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sip_);
1257 if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_SIP)) {
1258 tapinfo->tap_draw(tapinfo);
1259 tapinfo->redraw &= ~REDRAW_SIP;
1263 /****************************************************************************/
1265 /****************************************************************************/
1268 sip_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
1270 GString *error_string;
1272 error_string = register_tap_listener("sip", tap_base_to_id(tap_id_base, tap_id_offset_sip_), NULL,
1278 if (error_string != NULL) {
1279 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1280 "%s", error_string->str);
1281 g_string_free(error_string, TRUE);
1285 /****************************************************************************/
1287 remove_tap_listener_sip_calls(voip_calls_tapinfo_t *tap_id_base)
1289 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_sip_));
1292 /****************************************************************************/
1293 /* ***************************TAP for ISUP **********************************/
1294 /****************************************************************************/
1296 /****************************************************************************/
1297 /* whenever a isup_ packet is seen by the tap listener */
1299 isup_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *isup_info)
1301 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_isup_);
1302 voip_calls_info_t *tmp_listinfo;
1303 voip_calls_info_t *callsinfo = NULL;
1304 isup_calls_info_t *tmp_isupinfo;
1305 gboolean found = FALSE;
1306 gboolean forward = FALSE;
1307 gboolean right_pair;
1309 gchar *frame_label = NULL;
1310 gchar *comment = NULL;
1312 const isup_tap_rec_t *pi = (const isup_tap_rec_t *)isup_info;
1314 /* check if the lower layer is MTP matching the frame number */
1315 if (tapinfo->mtp3_frame_num != pinfo->num)
1318 /* check whether we already have a call with these parameters in the list */
1319 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
1323 tmp_listinfo=(voip_calls_info_t *)list->data;
1324 if ((tmp_listinfo->protocol == VOIP_ISUP)&&(tmp_listinfo->call_active_state==VOIP_ACTIVE)) {
1325 tmp_isupinfo = (isup_calls_info_t *)tmp_listinfo->prot_info;
1326 if ((tmp_isupinfo->cic == pi->circuit_id)&&(tmp_isupinfo->ni == tapinfo->mtp3_ni)) {
1327 if ((tmp_isupinfo->opc == tapinfo->mtp3_opc)&&(tmp_isupinfo->dpc == tapinfo->mtp3_dpc)) {
1329 } else if ((tmp_isupinfo->dpc == tapinfo->mtp3_opc)&&(tmp_isupinfo->opc == tapinfo->mtp3_dpc)) {
1336 /* if there is an IAM for a call that is not in setup state, that means the previous call in the same
1337 cic is no longer active */
1338 if (tmp_listinfo->call_state == VOIP_CALL_SETUP) {
1340 } else if (pi->message_type != 1) {
1343 tmp_listinfo->call_active_state=VOIP_INACTIVE;
1348 callsinfo = (voip_calls_info_t*)(list->data);
1353 list = g_list_next (list);
1356 /* not in the list? then create a new entry if the message is IAM
1357 -i.e. if this session is a call*/
1359 if ((callsinfo==NULL) &&(pi->message_type==1)) {
1360 callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
1361 callsinfo->call_active_state = VOIP_ACTIVE;
1362 callsinfo->call_state = VOIP_UNKNOWN;
1363 copy_address(&(callsinfo->initial_speaker),&(pinfo->src));
1364 callsinfo->selected=FALSE;
1365 callsinfo->start_fd=pinfo->fd;
1366 callsinfo->start_rel_ts=pinfo->rel_ts;
1367 callsinfo->protocol=VOIP_ISUP;
1368 if (pi->calling_number!=NULL) {
1369 callsinfo->from_identity=g_strdup(pi->calling_number);
1371 if (pi->called_number!=NULL) {
1372 callsinfo->to_identity=g_strdup(pi->called_number);
1374 callsinfo->prot_info=g_malloc(sizeof(isup_calls_info_t));
1375 callsinfo->free_prot_info = g_free;
1376 tmp_isupinfo=(isup_calls_info_t *)callsinfo->prot_info;
1377 tmp_isupinfo->opc = tapinfo->mtp3_opc;
1378 tmp_isupinfo->dpc = tapinfo->mtp3_dpc;
1379 tmp_isupinfo->ni = tapinfo->mtp3_ni;
1380 tmp_isupinfo->cic = pi->circuit_id;
1381 callsinfo->npackets = 0;
1382 callsinfo->call_num = tapinfo->ncalls++;
1383 g_queue_push_tail(tapinfo->callsinfos, callsinfo);
1387 if (callsinfo!=NULL) {
1388 callsinfo->stop_fd = pinfo->fd;
1389 callsinfo->stop_rel_ts = pinfo->rel_ts;
1390 ++(callsinfo->npackets);
1392 /* Let's analyze the call state */
1394 frame_label = g_strdup(val_to_str_ext_const(pi->message_type, &isup_message_type_value_acro_ext, "Unknown"));
1396 if (callsinfo->npackets == 1) { /* this is the first packet, that must be an IAM */
1398 if ((pi->calling_number!=NULL)&&(pi->called_number !=NULL)) {
1399 comment = g_strdup_printf("Call from %s to %s",
1400 pi->calling_number, pi->called_number);
1402 } else if (callsinfo->npackets == 2) { /* in the second packet we show the SPs */
1404 comment = g_strdup_printf("%i-%i -> %i-%i. Cic:%i",
1405 tapinfo->mtp3_ni, tapinfo->mtp3_opc,
1406 tapinfo->mtp3_ni, tapinfo->mtp3_dpc, pi->circuit_id);
1408 comment = g_strdup_printf("%i-%i -> %i-%i. Cic:%i",
1409 tapinfo->mtp3_ni, tapinfo->mtp3_dpc,
1410 tapinfo->mtp3_ni, tapinfo->mtp3_opc, pi->circuit_id);
1414 switch(pi->message_type) {
1416 callsinfo->call_state=VOIP_CALL_SETUP;
1418 case 7: /* CONNECT */
1419 case 9: /* ANSWER */
1420 callsinfo->call_state=VOIP_IN_CALL;
1422 case 12: /* RELEASE */
1423 if (callsinfo->call_state==VOIP_CALL_SETUP) {
1425 callsinfo->call_state=VOIP_CANCELLED;
1428 callsinfo->call_state=VOIP_REJECTED;
1429 tapinfo->rejected_calls++;
1432 else if (callsinfo->call_state == VOIP_IN_CALL) {
1433 callsinfo->call_state = VOIP_COMPLETED;
1434 tapinfo->completed_calls++;
1436 comment = g_strdup_printf("Cause %i - %s",
1438 val_to_str_ext_const(pi->cause_value, &q931_cause_code_vals_ext, "(Unknown)"));
1442 /* increment the packets counter of all calls */
1443 ++(tapinfo->npackets);
1445 /* add to the graph */
1446 add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
1448 g_free(frame_label);
1451 tapinfo->redraw |= REDRAW_ISUP;
1453 return TRUE; /* refresh output */
1456 /****************************************************************************/
1458 isup_calls_draw(void *tap_offset_ptr)
1460 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_isup_);
1462 if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_ISUP)) {
1463 tapinfo->tap_draw(tapinfo);
1464 tapinfo->redraw &= ~REDRAW_ISUP;
1468 /****************************************************************************/
1471 isup_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
1473 GString *error_string;
1475 error_string = register_tap_listener("isup", tap_base_to_id(tap_id_base, tap_id_offset_isup_),
1483 if (error_string != NULL) {
1484 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1485 "%s", error_string->str);
1486 g_string_free(error_string, TRUE);
1490 /****************************************************************************/
1493 remove_tap_listener_isup_calls(voip_calls_tapinfo_t *tap_id_base)
1495 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_isup_));
1498 /****************************************************************************/
1499 /* ***************************TAP for MTP3 **********************************/
1500 /****************************************************************************/
1503 /****************************************************************************/
1504 /* whenever a mtp3_ packet is seen by the tap listener */
1506 mtp3_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt _U_, const void *mtp3_info)
1508 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_mtp3_);
1509 const mtp3_tap_rec_t *pi = (const mtp3_tap_rec_t *)mtp3_info;
1511 /* keep the data in memory to use when the ISUP information arrives */
1513 tapinfo->mtp3_opc = pi->addr_opc.pc;
1514 tapinfo->mtp3_dpc = pi->addr_dpc.pc;
1515 tapinfo->mtp3_ni = pi->addr_opc.ni;
1516 tapinfo->mtp3_frame_num = pinfo->num;
1521 /****************************************************************************/
1524 mtp3_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
1526 GString *error_string;
1528 error_string = register_tap_listener("mtp3", tap_base_to_id(tap_id_base, tap_id_offset_mtp3_),
1536 if (error_string != NULL) {
1537 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1538 "%s", error_string->str);
1539 g_string_free(error_string, TRUE);
1542 error_string = register_tap_listener("m3ua", tap_base_to_id(tap_id_base, tap_id_offset_m3ua_),
1550 if (error_string != NULL) {
1551 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1552 "%s", error_string->str);
1553 g_string_free(error_string, TRUE);
1558 /****************************************************************************/
1561 remove_tap_listener_mtp3_calls(voip_calls_tapinfo_t *tap_id_base)
1563 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_mtp3_));
1564 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_m3ua_));
1567 /****************************************************************************/
1568 /* ***************************TAP for Q931 **********************************/
1569 /****************************************************************************/
1570 static void h245_add_to_graph(voip_calls_tapinfo_t *tapinfo, guint32 new_frame_num);
1571 static const e_guid_t guid_allzero = {0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } };
1572 /* defines specific H323 data */
1574 /****************************************************************************/
1575 /* whenever a q931_ packet is seen by the tap listener */
1577 q931_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *q931_info)
1580 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_q931_);
1581 h323_calls_info_t *tmp_h323info,*tmp2_h323info;
1582 actrace_isdn_calls_info_t *tmp_actrace_isdn_info;
1583 voip_calls_info_t *tmp_listinfo;
1584 voip_calls_info_t *callsinfo = NULL;
1585 h245_address_t *h245_add = NULL;
1586 gchar *comment, *tmp_str;
1588 const q931_packet_info *pi = (const q931_packet_info *)q931_info;
1590 /* free previously allocated q931_calling/ed_number */
1591 g_free(tapinfo->q931_calling_number);
1592 g_free(tapinfo->q931_called_number);
1594 if (pi->calling_number!=NULL)
1595 tapinfo->q931_calling_number = g_strdup(pi->calling_number);
1597 tapinfo->q931_calling_number = g_strdup("");
1599 if (pi->called_number!=NULL)
1600 tapinfo->q931_called_number = g_strdup(pi->called_number);
1602 tapinfo->q931_called_number = g_strdup("");
1603 tapinfo->q931_cause_value = pi->cause_value;
1604 tapinfo->q931_frame_num = pinfo->num;
1605 tapinfo->q931_crv = pi->crv;
1608 /* add staff to H323 calls */
1609 if (tapinfo->h225_frame_num == tapinfo->q931_frame_num) {
1610 tmp_h323info = NULL;
1611 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
1614 tmp_listinfo=(voip_calls_info_t *)list->data;
1615 if ( (tmp_listinfo->protocol == VOIP_H323) && (tmp_listinfo->call_num == tapinfo->h225_call_num) ) {
1616 tmp_h323info = (h323_calls_info_t *)tmp_listinfo->prot_info;
1617 callsinfo = (voip_calls_info_t*)(list->data);
1619 /* Add the CRV to the h323 call */
1620 if (tmp_h323info->q931_crv == -1) {
1621 tmp_h323info->q931_crv = tapinfo->q931_crv;
1622 } else if (tmp_h323info->q931_crv != tapinfo->q931_crv) {
1623 tmp_h323info->q931_crv2 = tapinfo->q931_crv;
1627 list = g_list_next (list);
1630 if (callsinfo != NULL) {
1632 if (tapinfo->h225_cstype == H225_SETUP) {
1633 /* set te calling and called number from the Q931 packet */
1634 if (tapinfo->q931_calling_number != NULL) {
1635 g_free(callsinfo->from_identity);
1636 callsinfo->from_identity=g_strdup(tapinfo->q931_calling_number);
1638 if (tapinfo->q931_called_number != NULL) {
1639 g_free(callsinfo->to_identity);
1640 callsinfo->to_identity=g_strdup(tapinfo->q931_called_number);
1643 /* check if there is an LRQ/LCF that match this Setup */
1644 /* TODO: we are just checking the DialedNumer in LRQ/LCF against the Setup
1645 we should also check if the h225 signaling IP and port match the destination
1646 Setup ip and port */
1647 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
1650 tmp_listinfo=(voip_calls_info_t *)list->data;
1651 if (tmp_listinfo->protocol == VOIP_H323) {
1652 tmp2_h323info = (h323_calls_info_t *)tmp_listinfo->prot_info;
1654 /* check if the called number match a LRQ/LCF */
1655 if ( (strcmp(callsinfo->to_identity, tmp_listinfo->to_identity)==0)
1656 && (memcmp(tmp2_h323info->guid, &guid_allzero, GUID_LEN) == 0) ) {
1657 /* change the call graph to the LRQ/LCF to belong to this call */
1658 callsinfo->npackets += change_call_num_graph(tapinfo, tmp_listinfo->call_num, callsinfo->call_num);
1660 /* remove this LRQ/LCF call entry because we have found the Setup that match them */
1661 g_free(tmp_listinfo->from_identity);
1662 g_free(tmp_listinfo->to_identity);
1663 DUMP_PTR2(tmp2_h323info->guid);
1664 g_free(tmp2_h323info->guid);
1666 list2 = g_list_first(tmp2_h323info->h245_list);
1669 h245_add=(h245_address_t *)list2->data;
1670 free_address(&h245_add->h245_address);
1671 g_free(list2->data);
1672 list2 = g_list_next(list2);
1674 g_list_free(tmp_h323info->h245_list);
1675 tmp_h323info->h245_list = NULL;
1676 g_free(tmp_listinfo->prot_info);
1677 g_queue_unlink(tapinfo->callsinfos, list);
1681 list = g_list_next (list);
1684 comment = g_strdup_printf("H225 From: %s To:%s TunnH245:%s FS:%s", callsinfo->from_identity, callsinfo->to_identity, (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
1685 (tapinfo->h225_is_faststart==TRUE?"on":"off"));
1686 } else if (tapinfo->h225_cstype == H225_RELEASE_COMPLET) {
1687 /* get the Q931 Release cause code */
1688 if (tapinfo->q931_cause_value != 0xFF) {
1689 comment = g_strdup_printf("H225 Q931 Rel Cause (%i):%s", tapinfo->q931_cause_value,
1690 val_to_str_ext_const(tapinfo->q931_cause_value, &q931_cause_code_vals_ext, "<unknown>"));
1691 } else { /* Cause not set */
1692 comment = g_strdup("H225 No Q931 Rel Cause");
1695 /* change the graph comment for this new one */
1696 if (comment != NULL) {
1697 change_frame_graph(tapinfo, tapinfo->h225_frame_num, NULL, comment);
1701 /* we reset the h225_frame_num to 0 because there could be empty h225 in the same frame
1702 as non empty h225 (e.g connect), so we don't have to be here twice */
1703 tapinfo->h225_frame_num = 0;
1705 /* add staff to H245 */
1706 } else if (tapinfo->h245_labels->frame_num == tapinfo->q931_frame_num) {
1707 /* there are empty H225 frames that don't have guid (guaid=0) but they have h245 info,
1708 so the only way to match those frames is with the Q931 CRV number */
1709 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
1712 tmp_listinfo=(voip_calls_info_t *)list->data;
1713 if (tmp_listinfo->protocol == VOIP_H323) {
1714 tmp_h323info = (h323_calls_info_t *)tmp_listinfo->prot_info;
1715 if ( ((tmp_h323info->q931_crv == tapinfo->q931_crv) || (tmp_h323info->q931_crv2 == tapinfo->q931_crv)) && (tapinfo->q931_crv!=-1)) {
1716 /* if the frame number exists in graph, append to it*/
1717 if (!append_to_frame_graph(tapinfo, tapinfo->q931_frame_num, NULL, NULL)) {
1718 /* if not exist, add to the graph */
1719 add_to_graph(tapinfo, pinfo, edt, NULL, NULL, tmp_listinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
1720 ++(tmp_listinfo->npackets);
1721 /* increment the packets counter of all calls */
1722 ++(tapinfo->npackets);
1725 /* Add the H245 info if exists to the Graph */
1726 h245_add_to_graph(tapinfo, pinfo->num);
1730 list = g_list_next (list);
1733 } else if (tapinfo->sip_frame_num == tapinfo->q931_frame_num) {
1734 /* Do nothing for now */
1735 /* add stuff to ACTRACE */
1741 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
1744 tmp_listinfo=(voip_calls_info_t *)list->data;
1745 if ( tmp_listinfo->protocol == VOIP_AC_ISDN ) {
1746 tmp_actrace_isdn_info = (actrace_isdn_calls_info_t *)tmp_listinfo->prot_info;
1747 /* TODO: Also check the IP of the Blade, and if the call is complete (no active) */
1748 if ( (tmp_actrace_isdn_info->crv == tapinfo->q931_crv) && (tmp_actrace_isdn_info->trunk == tapinfo->actrace_trunk) ) {
1749 callsinfo = (voip_calls_info_t*)(list->data);
1753 list = g_list_next (list);
1756 set_address(&pstn_add, AT_STRINGZ, 5, g_strdup("PSTN"));
1758 /* if it is a new call, add it to the list */
1760 callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
1761 callsinfo->call_active_state = VOIP_ACTIVE;
1762 callsinfo->call_state = VOIP_CALL_SETUP;
1763 callsinfo->from_identity=g_strdup(tapinfo->q931_calling_number);
1764 callsinfo->to_identity=g_strdup(tapinfo->q931_called_number);
1765 copy_address(&(callsinfo->initial_speaker),tapinfo->actrace_direction?&pstn_add:&(pinfo->src));
1766 callsinfo->selected=FALSE;
1767 callsinfo->start_fd=pinfo->fd;
1768 callsinfo->start_rel_ts=pinfo->rel_ts;
1769 callsinfo->protocol=VOIP_AC_ISDN;
1770 callsinfo->prot_info=g_malloc(sizeof(actrace_isdn_calls_info_t));
1771 callsinfo->free_prot_info = g_free;
1772 tmp_actrace_isdn_info=(actrace_isdn_calls_info_t *)callsinfo->prot_info;
1773 tmp_actrace_isdn_info->crv=tapinfo->q931_crv;
1774 tmp_actrace_isdn_info->trunk=tapinfo->actrace_trunk;
1775 callsinfo->npackets = 0;
1776 callsinfo->call_num = tapinfo->ncalls++;
1777 g_queue_push_tail(tapinfo->callsinfos, callsinfo);
1780 callsinfo->stop_fd = pinfo->fd;
1781 callsinfo->stop_rel_ts = pinfo->rel_ts;
1782 ++(callsinfo->npackets);
1783 /* increment the packets counter of all calls */
1784 ++(tapinfo->npackets);
1786 switch(pi->message_type) {
1788 comment = g_strdup_printf("AC_ISDN trunk:%u Calling: %s Called:%s", tapinfo->actrace_trunk, tapinfo->q931_calling_number, tapinfo->q931_called_number);
1789 callsinfo->call_state=VOIP_CALL_SETUP;
1792 callsinfo->call_state=VOIP_IN_CALL;
1794 case Q931_RELEASE_COMPLETE:
1796 case Q931_DISCONNECT:
1797 if (callsinfo->call_state==VOIP_CALL_SETUP) {
1798 if (addresses_equal(&(callsinfo->initial_speaker), tapinfo->actrace_direction?&pstn_add:&(pinfo->src) )) { /* forward direction */
1799 callsinfo->call_state=VOIP_CANCELLED;
1801 else { /* reverse */
1802 callsinfo->call_state=VOIP_REJECTED;
1803 tapinfo->rejected_calls++;
1805 } else if ( (callsinfo->call_state!=VOIP_CANCELLED) && (callsinfo->call_state!=VOIP_REJECTED) ) {
1806 callsinfo->call_state=VOIP_COMPLETED;
1807 tapinfo->completed_calls++;
1809 if (tapinfo->q931_cause_value != 0xFF) {
1810 comment = g_strdup_printf("AC_ISDN trunk:%u Q931 Rel Cause (%i):%s", tapinfo->actrace_trunk, tapinfo->q931_cause_value,
1811 val_to_str_ext_const(tapinfo->q931_cause_value, &q931_cause_code_vals_ext, "<unknown>"));
1812 } else { /* Cause not set */
1813 comment = g_strdup("AC_ISDN No Q931 Rel Cause");
1819 comment = g_strdup_printf("AC_ISDN trunk:%u", tapinfo->actrace_trunk );
1821 tmp_str = val_to_str_wmem(NULL, pi->message_type, q931_message_type_vals, "<unknown (%d)>");
1822 add_to_graph(tapinfo, pinfo, edt, tmp_str, comment, callsinfo->call_num,
1823 tapinfo->actrace_direction?&pstn_add:&(pinfo->src),
1824 tapinfo->actrace_direction?&(pinfo->src):&pstn_add,
1826 wmem_free(NULL, tmp_str);
1829 free_address(&pstn_add);
1832 tapinfo->redraw |= REDRAW_Q931;
1834 return TRUE; /* refresh output */
1837 /****************************************************************************/
1839 q931_calls_draw(void *tap_offset_ptr)
1841 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_q931_);
1843 if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_Q931)) {
1844 tapinfo->tap_draw(tapinfo);
1845 tapinfo->redraw &= ~REDRAW_Q931;
1849 /****************************************************************************/
1852 q931_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
1854 GString *error_string;
1856 error_string = register_tap_listener("q931", tap_base_to_id(tap_id_base, tap_id_offset_q931_),
1864 if (error_string != NULL) {
1865 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1866 "%s", error_string->str);
1867 g_string_free(error_string, TRUE);
1871 /****************************************************************************/
1874 remove_tap_listener_q931_calls(voip_calls_tapinfo_t *tap_id_base)
1876 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_q931_));
1879 /****************************************************************************/
1880 /****************************TAP for H323 ***********************************/
1881 /****************************************************************************/
1884 add_h245_Address(h323_calls_info_t *h323info, h245_address_t *h245_address)
1886 h323info->h245_list = g_list_prepend(h323info->h245_list, h245_address);
1891 free_h225_info(gpointer p) {
1892 h323_calls_info_t *tmp_h323info = (h323_calls_info_t *)p;
1894 DUMP_PTR2(tmp_h323info->guid);
1895 g_free(tmp_h323info->guid);
1897 if (tmp_h323info->h245_list) {
1898 GList *list2 = g_list_first(tmp_h323info->h245_list);
1901 h245_address_t *h245_add=(h245_address_t *)list2->data;
1902 free_address(&h245_add->h245_address);
1903 g_free(list2->data);
1904 list2 = g_list_next(list2);
1907 g_list_free(tmp_h323info->h245_list);
1913 /****************************************************************************/
1914 /* whenever a H225 packet is seen by the tap listener */
1916 h225_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *H225info)
1918 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_h225_);
1919 voip_calls_info_t *tmp_listinfo;
1920 voip_calls_info_t *callsinfo = NULL;
1921 h323_calls_info_t *tmp_h323info = NULL;
1925 h245_address_t *h245_add = NULL;
1927 const h225_packet_info *pi = (const h225_packet_info *)H225info;
1929 /* if not guid and RAS and not LRQ, LCF or LRJ return because did not belong to a call */
1930 /* OR, if not guid and is H225 return because doesn't belong to a call */
1931 if ((memcmp(&pi->guid, &guid_allzero, GUID_LEN) == 0))
1932 if ( ((pi->msg_type == H225_RAS) && ((pi->msg_tag < 18) || (pi->msg_tag > 20))) || (pi->msg_type != H225_RAS) )
1935 /* if it is RAS LCF or LRJ*/
1936 if ( (pi->msg_type == H225_RAS) && ((pi->msg_tag == 19) || (pi->msg_tag == 20))) {
1937 /* if the LCF/LRJ doesn't match to a LRQ, just return */
1938 if (!pi->request_available) return FALSE;
1940 /* check whether we already have a call with this request SeqNum */
1941 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
1944 tmp_listinfo=(voip_calls_info_t *)list->data;
1945 g_assert(tmp_listinfo != NULL);
1946 if (tmp_listinfo->protocol == VOIP_H323) {
1947 tmp_h323info = (h323_calls_info_t *)tmp_listinfo->prot_info;
1948 if (tmp_h323info->requestSeqNum == pi->requestSeqNum) {
1949 callsinfo = (voip_calls_info_t*)(list->data);
1953 list = g_list_next (list);
1956 /* check whether we already have a call with this guid in the list */
1957 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
1960 tmp_listinfo=(voip_calls_info_t *)list->data;
1961 if (tmp_listinfo->protocol == VOIP_H323) {
1962 tmp_h323info = (h323_calls_info_t *)tmp_listinfo->prot_info;
1963 g_assert(tmp_h323info != NULL);
1964 if ( (memcmp(tmp_h323info->guid, &guid_allzero, GUID_LEN) != 0) && (memcmp(tmp_h323info->guid, &pi->guid,GUID_LEN)==0) ) {
1965 callsinfo = (voip_calls_info_t*)(list->data);
1969 list = g_list_next (list);
1973 tapinfo->h225_cstype = pi->cs_type;
1974 tapinfo->h225_is_faststart = pi->is_faststart;
1976 /* not in the list? then create a new entry */
1977 if (callsinfo==NULL) {
1978 callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
1979 callsinfo->call_active_state = VOIP_ACTIVE;
1980 callsinfo->call_state = VOIP_UNKNOWN;
1981 callsinfo->from_identity=g_strdup("");
1982 callsinfo->to_identity=g_strdup("");
1983 copy_address(&(callsinfo->initial_speaker),&(pinfo->src));
1984 callsinfo->selected=FALSE;
1985 callsinfo->start_fd=pinfo->fd;
1986 callsinfo->start_rel_ts=pinfo->rel_ts;
1987 callsinfo->protocol=VOIP_H323;
1988 callsinfo->prot_info=g_malloc(sizeof(h323_calls_info_t));
1989 callsinfo->free_prot_info = free_h225_info;
1991 tmp_h323info = (h323_calls_info_t *)callsinfo->prot_info;
1992 g_assert(tmp_h323info != NULL);
1993 tmp_h323info->guid = (e_guid_t *)g_memdup(&pi->guid, sizeof pi->guid);
1994 DUMP_PTR1(tmp_h323info->guid);
1996 clear_address(&tmp_h323info->h225SetupAddr);
1997 tmp_h323info->h245_list = NULL;
1998 tmp_h323info->is_faststart_Setup = FALSE;
1999 tmp_h323info->is_faststart_Proc = FALSE;
2000 tmp_h323info->is_h245Tunneling = FALSE;
2001 tmp_h323info->is_h245 = FALSE;
2002 tmp_h323info->q931_crv = -1;
2003 tmp_h323info->q931_crv2 = -1;
2004 tmp_h323info->requestSeqNum = 0;
2005 callsinfo->call_num = tapinfo->ncalls++;
2006 callsinfo->npackets = 0;
2008 g_queue_push_tail(tapinfo->callsinfos, callsinfo);
2011 tapinfo->h225_frame_num = pinfo->num;
2012 tapinfo->h225_call_num = callsinfo->call_num;
2014 /* let's analyze the call state */
2016 callsinfo->stop_fd = pinfo->fd;
2017 callsinfo->stop_rel_ts = pinfo->rel_ts;
2018 ++(callsinfo->npackets);
2019 /* increment the packets counter of all calls */
2020 ++(tapinfo->npackets);
2023 /* XXX: it is supposed to be initialized isn't it? */
2024 g_assert(tmp_h323info != NULL);
2026 /* change the status */
2027 if (pi->msg_type == H225_CS) {
2029 /* this is still IPv4 only, because the dissector is */
2030 if (pi->is_h245 == TRUE) {
2031 h245_add = (h245_address_t *)g_malloc(sizeof (h245_address_t));
2032 alloc_address_wmem(NULL, &h245_add->h245_address, AT_IPv4, 4, &pi->h245_address);
2033 h245_add->h245_port = pi->h245_port;
2034 add_h245_Address(tmp_h323info, h245_add);
2037 if (pi->cs_type != H225_RELEASE_COMPLET) tmp_h323info->is_h245Tunneling = pi->is_h245Tunneling;
2039 frame_label = g_strdup(pi->frame_label);
2041 switch(pi->cs_type) {
2043 tmp_h323info->is_faststart_Setup = pi->is_faststart;
2045 /* Set the Setup address if it was not set */
2046 if (tmp_h323info->h225SetupAddr.type == AT_NONE)
2047 copy_address(&(tmp_h323info->h225SetupAddr), &(pinfo->src));
2048 callsinfo->call_state=VOIP_CALL_SETUP;
2049 comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
2050 (pi->is_faststart==TRUE?"on":"off"));
2053 callsinfo->call_state=VOIP_IN_CALL;
2054 if (pi->is_faststart == TRUE) tmp_h323info->is_faststart_Proc = TRUE;
2055 comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
2056 (pi->is_faststart==TRUE?"on":"off"));
2058 case H225_RELEASE_COMPLET:
2059 if (callsinfo->call_state==VOIP_CALL_SETUP) {
2060 if (addresses_equal(&(tmp_h323info->h225SetupAddr),&(pinfo->src))) { /* forward direction */
2061 callsinfo->call_state=VOIP_CANCELLED;
2063 else { /* reverse */
2064 callsinfo->call_state=VOIP_REJECTED;
2065 tapinfo->rejected_calls++;
2068 callsinfo->call_state=VOIP_COMPLETED;
2069 tapinfo->completed_calls++;
2071 comment = g_strdup("H225 No Q931 Rel Cause");
2075 case H225_CALL_PROCEDING:
2076 if (pi->is_faststart == TRUE) tmp_h323info->is_faststart_Proc = TRUE;
2077 comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
2078 (pi->is_faststart==TRUE?"on":"off"));
2081 comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
2082 (pi->is_faststart==TRUE?"on":"off"));
2086 else if (pi->msg_type == H225_RAS) {
2087 switch(pi->msg_tag) {
2089 if (!pi->is_duplicate) {
2090 g_free(callsinfo->to_identity);
2091 callsinfo->to_identity=g_strdup(pi->dialedDigits);
2092 tmp_h323info->requestSeqNum = pi->requestSeqNum;
2096 if (strlen(pi->dialedDigits))
2097 comment = g_strdup_printf("H225 RAS dialedDigits: %s", pi->dialedDigits);
2099 comment = g_strdup("H225 RAS");
2102 comment = g_strdup("H225 RAS");
2104 frame_label = g_strdup(val_to_str_const(pi->msg_tag, h225_RasMessage_vals, "<unknown>"));
2106 frame_label = g_strdup("H225: Unknown");
2110 /* add to graph analysis */
2112 /* if the frame number exists in graph, append to it*/
2113 if (!append_to_frame_graph(tapinfo, pinfo->num, pi->frame_label, comment)) {
2114 /* if not exist, add to the graph */
2115 add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
2118 /* Add the H245 info if exists to the Graph */
2119 h245_add_to_graph(tapinfo, pinfo->num);
2121 g_free(frame_label);
2124 tapinfo->redraw |= REDRAW_H225;
2126 return TRUE; /* refresh output */
2129 /****************************************************************************/
2131 h225_calls_draw(void *tap_offset_ptr)
2133 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_h225_);
2135 if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_H225)) {
2136 tapinfo->tap_draw(tapinfo);
2137 tapinfo->redraw &= ~REDRAW_H225;
2141 /****************************************************************************/
2143 /****************************************************************************/
2145 h225_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
2147 GString *error_string;
2149 error_string = register_tap_listener("h225", tap_base_to_id(tap_id_base, tap_id_offset_h225_), NULL,
2156 if (error_string != NULL) {
2157 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2158 "%s", error_string->str);
2159 g_string_free(error_string, TRUE);
2163 /****************************************************************************/
2165 remove_tap_listener_h225_calls(voip_calls_tapinfo_t *tap_id_base)
2167 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_h225_));
2170 /* Add the h245 label info to the graph */
2172 h245_add_to_graph(voip_calls_tapinfo_t *tapinfo, guint32 new_frame_num)
2176 if (new_frame_num != tapinfo->h245_labels->frame_num) return;
2178 for (n=0; n<tapinfo->h245_labels->labels_count; n++) {
2179 append_to_frame_graph(tapinfo, new_frame_num, tapinfo->h245_labels->labels[n].frame_label, tapinfo->h245_labels->labels[n].comment);
2180 g_free(tapinfo->h245_labels->labels[n].frame_label);
2181 tapinfo->h245_labels->labels[n].frame_label = NULL;
2182 g_free(tapinfo->h245_labels->labels[n].comment);
2183 tapinfo->h245_labels->labels[n].comment = NULL;
2185 tapinfo->h245_labels->frame_num = 0;
2186 tapinfo->h245_labels->labels_count = 0;
2189 /* free the h245_labels if the frame number is different */
2191 h245_free_labels(voip_calls_tapinfo_t *tapinfo, guint32 new_frame_num)
2195 if (new_frame_num == tapinfo->h245_labels->frame_num) return;
2197 for (n=0; n<tapinfo->h245_labels->labels_count; n++) {
2198 g_free(tapinfo->h245_labels->labels[n].frame_label);
2199 tapinfo->h245_labels->labels[n].frame_label = NULL;
2200 g_free(tapinfo->h245_labels->labels[n].comment);
2201 tapinfo->h245_labels->labels[n].comment = NULL;
2203 tapinfo->h245_labels->frame_num = 0;
2204 tapinfo->h245_labels->labels_count = 0;
2207 /* add the frame_label and comment to h245_labels and free the actual one if it is different frame num */
2209 h245_add_label(voip_calls_tapinfo_t *tapinfo, guint32 new_frame_num, const gchar *frame_label, const gchar *comment)
2211 h245_free_labels(tapinfo, new_frame_num);
2213 tapinfo->h245_labels->frame_num = new_frame_num;
2214 tapinfo->h245_labels->labels[tapinfo->h245_labels->labels_count].frame_label = g_strdup(frame_label);
2215 tapinfo->h245_labels->labels[tapinfo->h245_labels->labels_count].comment = g_strdup(comment);
2217 if (tapinfo->h245_labels->labels_count < (H245_MAX-1))
2218 tapinfo->h245_labels->labels_count++;
2222 /****************************************************************************/
2223 /* whenever a H245dg packet is seen by the tap listener (when H245 tunneling is ON) */
2225 h245dg_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *H245info)
2227 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_h245dg_);
2228 voip_calls_info_t *tmp_listinfo;
2229 voip_calls_info_t *callsinfo = NULL;
2230 h323_calls_info_t *tmp_h323info;
2233 h245_address_t *h245_add = NULL;
2235 const h245_packet_info *pi = (const h245_packet_info *)H245info;
2237 /* check if Tunneling is OFF and we have a call with this H245 add */
2238 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
2241 tmp_listinfo=(voip_calls_info_t *)list->data;
2242 if (tmp_listinfo->protocol == VOIP_H323) {
2243 tmp_h323info = (h323_calls_info_t *)tmp_listinfo->prot_info;
2245 list2 = g_list_first(tmp_h323info->h245_list);
2248 h245_add=(h245_address_t *)list2->data;
2249 if ( (addresses_equal(&(h245_add->h245_address),&(pinfo->src)) && (h245_add->h245_port == pinfo->srcport))
2250 || (addresses_equal(&(h245_add->h245_address),&(pinfo->dst)) && (h245_add->h245_port == pinfo->destport)) ) {
2251 callsinfo = (voip_calls_info_t*)(list->data);
2253 ++(callsinfo->npackets);
2254 /* increment the packets counter of all calls */
2255 ++(tapinfo->npackets);
2259 list2 = g_list_next(list2);
2261 if (callsinfo!=NULL) break;
2263 list = g_list_next(list);
2266 /* Tunnel is OFF, and we matched the h245 add so we add it to graph */
2267 if (callsinfo!=NULL) {
2268 ++(callsinfo->npackets);
2269 /* increment the packets counter of all calls */
2270 ++(tapinfo->npackets);
2271 /* if the frame number exists in graph, append to it*/
2272 if (!append_to_frame_graph(tapinfo, pinfo->num, pi->frame_label, pi->comment)) {
2273 /* if not exist, add to the graph */
2274 add_to_graph(tapinfo, pinfo, edt, pi->frame_label, pi->comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
2277 /* Tunnel is ON, so we save the label info to use it into h225 or q931 tap. OR may be
2278 tunnel OFF but we did not matched the h245 add, in this case nobady will set this label
2279 since the frame_num will not match */
2281 h245_add_label(tapinfo, pinfo->num, (gchar *) pi->frame_label, (gchar *) pi->comment);
2284 tapinfo->redraw |= REDRAW_H245DG;
2286 return TRUE; /* refresh output */
2289 /****************************************************************************/
2291 h245dg_calls_draw(void *tap_offset_ptr)
2293 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_h245dg_);
2295 if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_H245DG)) {
2296 tapinfo->tap_draw(tapinfo);
2297 tapinfo->redraw &= ~REDRAW_H245DG;
2301 /****************************************************************************/
2303 /****************************************************************************/
2305 h245dg_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
2307 GString *error_string;
2309 if (!tap_id_base->h245_labels) {
2310 tap_id_base->h245_labels = g_new0(h245_labels_t, 1);
2313 error_string = register_tap_listener("h245dg", tap_base_to_id(tap_id_base, tap_id_offset_h245dg_), NULL,
2316 h245dg_calls_packet,
2320 if (error_string != NULL) {
2321 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2322 "%s", error_string->str);
2323 g_string_free(error_string, TRUE);
2327 /****************************************************************************/
2329 remove_tap_listener_h245dg_calls(voip_calls_tapinfo_t *tap_id_base)
2331 if (tap_id_base->h245_labels) {
2332 g_free(tap_id_base->h245_labels);
2333 tap_id_base->h245_labels = NULL;
2335 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_h245dg_));
2338 /****************************************************************************/
2339 /****************************TAP for SDP PROTOCOL ***************************/
2340 /****************************************************************************/
2341 /* whenever a SDP packet is seen by the tap listener */
2343 sdp_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt _U_, const void *SDPinfo)
2345 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sdp_);
2346 const sdp_packet_info *pi = (const sdp_packet_info *)SDPinfo;
2348 /* There are protocols like MGCP/SIP where the SDP is called before the tap for the
2349 MGCP/SIP packet, in those cases we assign the SPD summary to global lastSDPsummary
2352 g_free(tapinfo->sdp_summary);
2353 tapinfo->sdp_frame_num = pinfo->num;
2354 /* Append to graph the SDP summary if the packet exists */
2355 tapinfo->sdp_summary = g_strdup_printf("SDP (%s)", pi->summary_str);
2356 append_to_frame_graph(tapinfo, pinfo->num, tapinfo->sdp_summary, NULL);
2358 tapinfo->redraw |= REDRAW_SDP;
2360 return TRUE; /* refresh output */
2363 /****************************************************************************/
2365 sdp_calls_draw(void *tap_offset_ptr)
2367 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sdp_);
2369 if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_SDP)) {
2370 tapinfo->tap_draw(tapinfo);
2371 tapinfo->redraw &= ~REDRAW_SDP;
2375 /****************************************************************************/
2377 /****************************************************************************/
2379 sdp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
2381 GString *error_string;
2383 error_string = register_tap_listener("sdp", tap_base_to_id(tap_id_base, tap_id_offset_sdp_), NULL,
2390 if (error_string != NULL) {
2391 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2392 "%s", error_string->str);
2393 g_string_free(error_string, TRUE);
2397 /****************************************************************************/
2399 remove_tap_listener_sdp_calls(voip_calls_tapinfo_t *tap_id_base)
2401 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_sdp_));
2404 /****************************************************************************/
2405 /* ***************************TAP for MGCP **********************************/
2406 /****************************************************************************/
2409 This function will look for a signal/event in the SignalReq/ObsEvent string
2410 and return true if it is found
2413 is_mgcp_signal(const gchar *signal_str_p, const gchar *signalStr)
2416 gchar **resultArray;
2418 /* if there is no signalStr, just return false */
2419 if (signalStr == NULL) return FALSE;
2421 /* if are both "blank" return true */
2422 if ( (*signal_str_p == '\0') && (*signalStr == '\0') ) return TRUE;
2424 /* look for signal in signalStr */
2425 resultArray = g_strsplit(signalStr, ",", 10);
2427 for (i = 0; resultArray[i]; i++) {
2428 g_strstrip(resultArray[i]);
2429 if (strcmp(resultArray[i], signal_str_p) == 0) return TRUE;
2432 g_strfreev(resultArray);
2438 This function will get the Caller ID info and replace the current string
2439 This is how it looks the caller Id: rg, ci(02/16/08/29, "3035550002","Ale Sipura 2")
2442 mgcp_caller_id(gchar *signalStr, gchar **callerId)
2446 /* if there is no signalStr, just return false */
2447 if (signalStr == NULL) return;
2449 arrayStr = g_strsplit(signalStr, "\"", 3);
2451 /* look for the ci signal */
2452 if (g_strv_length(arrayStr) == 3 && strstr(arrayStr[0], "ci(")) {
2453 /* free the previous "From" field of the call, and assign the new */
2455 *callerId = g_strdup(arrayStr[1]);
2457 g_strfreev(arrayStr);
2461 This function will get the Dialed Digits and replace the current string
2462 This is how it looks the dialed digits 5,5,5,0,0,0,2,#,*
2465 mgcp_dialed_digits(gchar *signalStr, gchar **dialedDigits)
2471 /* start with 1 for the null-terminator */
2472 guint resultStrLen = 1;
2474 /* if there is no signalStr, just return false */
2475 if (signalStr == NULL) return;
2477 tmpStr = g_strdup(signalStr);
2479 for ( i = 0 ; tmpStr[i] ; i++) {
2480 switch (tmpStr[i]) {
2481 case '0' : case '1' : case '2' : case '3' : case '4' :
2482 case '5' : case '6' : case '7' : case '8' : case '9' :
2483 case '#' : case '*' :
2492 if (resultStrLen == 1) {
2497 resultStr = (gchar *)g_malloc(resultStrLen);
2499 for (i = 0, j = 0; tmpStr[i]; i++) {
2500 if (tmpStr[i] != '?')
2501 resultStr[j++] = tmpStr[i];
2503 resultStr[j] = '\0';
2505 g_free(*dialedDigits);
2508 *dialedDigits = resultStr;
2515 /****************************************************************************/
2516 /* whenever a MGCP packet is seen by the tap listener */
2518 mgcp_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *MGCPinfo)
2520 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_mgcp_);
2521 voip_calls_info_t *tmp_listinfo;
2522 voip_calls_info_t *callsinfo = NULL;
2523 mgcp_calls_info_t *tmp_mgcpinfo = NULL;
2525 GList *listGraph = NULL;
2526 gchar *frame_label = NULL;
2527 gchar *comment = NULL;
2528 seq_analysis_item_t *gai = NULL;
2529 gboolean newcall = FALSE;
2530 gboolean fromEndpoint = FALSE; /* true for calls originated in Endpoints, false for calls from MGC */
2533 const mgcp_info_t *pi = (const mgcp_info_t *)MGCPinfo;
2536 if ((pi->mgcp_type == MGCP_REQUEST) && !pi->is_duplicate ) {
2537 /* check whether we already have a call with this Endpoint and it is active*/
2538 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
2541 tmp_listinfo=(voip_calls_info_t *)list->data;
2542 if ((tmp_listinfo->protocol == VOIP_MGCP) && (tmp_listinfo->call_active_state == VOIP_ACTIVE)) {
2543 tmp_mgcpinfo = (mgcp_calls_info_t *)tmp_listinfo->prot_info;
2544 if (pi->endpointId != NULL) {
2545 if (g_ascii_strcasecmp(tmp_mgcpinfo->endpointId,pi->endpointId) == 0) {
2547 check first if it is an ended call. We can still match packets to this Endpoint 2 seconds
2548 after the call has been released
2550 diff_time = nstime_to_sec(&pinfo->rel_ts) - nstime_to_sec(&tmp_listinfo->stop_rel_ts);
2551 if ( ((tmp_listinfo->call_state == VOIP_CANCELLED) ||
2552 (tmp_listinfo->call_state == VOIP_COMPLETED) ||
2553 (tmp_listinfo->call_state == VOIP_REJECTED)) &&
2556 tmp_listinfo->call_active_state = VOIP_INACTIVE;
2558 callsinfo = (voip_calls_info_t*)(list->data);
2564 list = g_list_next (list);
2567 /* there is no call with this Endpoint, lets see if this a new call or not */
2568 if (callsinfo == NULL) {
2569 if ( (strcmp(pi->code, "NTFY") == 0) && is_mgcp_signal("hd", pi->observedEvents) ) { /* off hook transition */
2570 /* this is a new call from the Endpoint */
2571 fromEndpoint = TRUE;
2573 } else if (strcmp(pi->code, "CRCX") == 0) {
2574 /* this is a new call from the MGC */
2575 fromEndpoint = FALSE;
2578 if (!newcall) return FALSE;
2580 } else if ( ((pi->mgcp_type == MGCP_RESPONSE) && pi->request_available) ||
2581 ((pi->mgcp_type == MGCP_REQUEST) && pi->is_duplicate) ) {
2582 /* if it is a response OR if it is a duplicated Request, lets look in the Graph to see
2583 if there is a request that matches */
2584 if(tapinfo->graph_analysis){
2585 listGraph = g_queue_peek_nth_link(tapinfo->graph_analysis->items, 0);
2589 gai = (seq_analysis_item_t *)listGraph->data;
2590 if (gai->frame_number == pi->req_num) {
2591 /* there is a request that match, so look the associated call with this call_num */
2592 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
2595 tmp_listinfo=(voip_calls_info_t *)list->data;
2596 if (tmp_listinfo->protocol == VOIP_MGCP) {
2597 if (tmp_listinfo->call_num == gai->conv_num) {
2598 tmp_mgcpinfo = (mgcp_calls_info_t *)tmp_listinfo->prot_info;
2599 callsinfo = (voip_calls_info_t*)(list->data);
2603 list = g_list_next (list);
2605 if (callsinfo != NULL) break;
2607 listGraph = g_list_next(listGraph);
2609 /* if there is not a matching request, just return */
2610 if (callsinfo == NULL) return FALSE;
2611 } else return FALSE;
2613 /* not in the list? then create a new entry */
2614 if (callsinfo==NULL) {
2615 callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
2616 callsinfo->call_active_state = VOIP_ACTIVE;
2617 callsinfo->call_state = VOIP_CALL_SETUP;
2619 callsinfo->from_identity=g_strdup(pi->endpointId);
2620 callsinfo->to_identity=g_strdup("");
2622 callsinfo->from_identity=g_strdup("");
2623 callsinfo->to_identity=g_strdup(pi->endpointId);
2625 copy_address(&(callsinfo->initial_speaker),&(pinfo->src));
2626 callsinfo->selected=FALSE;
2627 callsinfo->start_fd=pinfo->fd;
2628 callsinfo->start_rel_ts=pinfo->rel_ts;
2629 callsinfo->protocol=VOIP_MGCP;
2630 callsinfo->prot_info=g_malloc(sizeof(mgcp_calls_info_t));
2631 callsinfo->free_prot_info = g_free;
2632 tmp_mgcpinfo=(mgcp_calls_info_t *)callsinfo->prot_info;
2633 tmp_mgcpinfo->endpointId = g_strdup(pi->endpointId);
2634 tmp_mgcpinfo->fromEndpoint = fromEndpoint;
2635 callsinfo->npackets = 0;
2636 callsinfo->call_num = tapinfo->ncalls++;
2637 g_queue_push_tail(tapinfo->callsinfos, callsinfo);
2640 g_assert(tmp_mgcpinfo != NULL);
2642 /* change call state and add to graph */
2643 switch (pi->mgcp_type)
2646 if ( (strcmp(pi->code, "NTFY") == 0) && (pi->observedEvents != NULL) ) {
2647 frame_label = g_strdup_printf("%s ObsEvt:%s",pi->code, pi->observedEvents);
2649 if (tmp_mgcpinfo->fromEndpoint) {
2650 /* use the Dialed digits to fill the "To" for the call, but use the first NTFY */
2651 if (callsinfo->to_identity[0] == '\0') mgcp_dialed_digits(pi->observedEvents, &(callsinfo->to_identity));
2653 /* from MGC and the user picked up, the call is connected */
2654 } else if (is_mgcp_signal("hd", pi->observedEvents))
2655 callsinfo->call_state=VOIP_IN_CALL;
2657 /* hung up signal */
2658 if (is_mgcp_signal("hu", pi->observedEvents)) {
2659 if ((callsinfo->call_state == VOIP_CALL_SETUP) || (callsinfo->call_state == VOIP_RINGING)) {
2660 callsinfo->call_state = VOIP_CANCELLED;
2662 callsinfo->call_state = VOIP_COMPLETED;
2666 } else if (strcmp(pi->code, "RQNT") == 0) {
2667 /* for calls from Endpoint: if there is a "no signal" RQNT and the call was RINGING, we assume this is the CONNECT */
2668 if ( tmp_mgcpinfo->fromEndpoint && is_mgcp_signal("", pi->signalReq) && (callsinfo->call_state == VOIP_RINGING) ) {
2669 callsinfo->call_state = VOIP_IN_CALL;
2672 /* if there is ringback or ring tone, change state to ringing */
2673 if ( is_mgcp_signal("rg", pi->signalReq) || is_mgcp_signal("rt", pi->signalReq) ) {
2674 callsinfo->call_state = VOIP_RINGING;
2677 /* if there is a Busy or ReorderTone, and the call was Ringing or Setup the call is Rejected */
2678 if ( (is_mgcp_signal("ro", pi->signalReq) || is_mgcp_signal("bz", pi->signalReq)) && ((callsinfo->call_state == VOIP_CALL_SETUP) || (callsinfo->call_state == VOIP_RINGING)) ) {
2679 callsinfo->call_state = VOIP_REJECTED;
2682 if (pi->signalReq != NULL)
2683 frame_label = g_strdup_printf("%s%sSigReq:%s",pi->code, (pi->hasDigitMap == TRUE)?" DigitMap ":"", pi->signalReq);
2685 frame_label = g_strdup_printf("%s%s",pi->code, (pi->hasDigitMap == TRUE)?" DigitMap ":"");
2687 /* use the CallerID info to fill the "From" for the call */
2688 if (!tmp_mgcpinfo->fromEndpoint) mgcp_caller_id(pi->signalReq, &(callsinfo->from_identity));
2690 } else if (strcmp(pi->code, "DLCX") == 0) {
2692 if there is a DLCX in a call To an Endpoint and the call was not connected, we use
2693 the DLCX as the end of the call
2695 if (!tmp_mgcpinfo->fromEndpoint) {
2696 if ((callsinfo->call_state == VOIP_CALL_SETUP) || (callsinfo->call_state == VOIP_RINGING)) {
2697 callsinfo->call_state = VOIP_CANCELLED;
2702 if (frame_label == NULL) frame_label = g_strdup(pi->code);
2705 frame_label = g_strdup_printf("%u (%s)",pi->rspcode, pi->code);
2708 /* XXX what to do? */
2712 comment = g_strdup_printf("MGCP %s %s%s", tmp_mgcpinfo->endpointId, (pi->mgcp_type == MGCP_REQUEST)?"Request":"Response", pi->is_duplicate?" Duplicate":"");
2714 callsinfo->stop_fd = pinfo->fd;
2715 callsinfo->stop_rel_ts = pinfo->rel_ts;
2716 ++(callsinfo->npackets);
2717 /* increment the packets counter of all calls */
2718 ++(tapinfo->npackets);
2720 /* add to the graph */
2721 add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
2723 g_free(frame_label);
2725 /* add SDP info if apply */
2726 if ( (tapinfo->sdp_summary != NULL) && (tapinfo->sdp_frame_num == pinfo->num) ) {
2727 append_to_frame_graph(tapinfo, pinfo->num, tapinfo->sdp_summary, NULL);
2728 g_free(tapinfo->sdp_summary);
2729 tapinfo->sdp_summary = NULL;
2732 tapinfo->redraw |= REDRAW_MGCP;
2734 return TRUE; /* refresh output */
2737 /****************************************************************************/
2739 mgcp_calls_draw(void *tap_offset_ptr)
2741 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_mgcp_);
2743 if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_MGCP)) {
2744 tapinfo->tap_draw(tapinfo);
2745 tapinfo->redraw &= ~REDRAW_MGCP;
2749 /****************************************************************************/
2751 /****************************************************************************/
2753 mgcp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
2755 GString *error_string;
2758 * We set TL_REQUIRES_PROTO_TREE to force a non-null "tree"
2759 * in the MGCP dissector; otherwise, the dissector
2760 * doesn't fill in the info passed to the tap's packet
2763 error_string = register_tap_listener("mgcp",
2764 tap_base_to_id(tap_id_base, tap_id_offset_mgcp_),
2766 TL_REQUIRES_PROTO_TREE,
2771 if (error_string != NULL) {
2772 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2773 "%s", error_string->str);
2774 g_string_free(error_string, TRUE);
2778 /****************************************************************************/
2780 remove_tap_listener_mgcp_calls(voip_calls_tapinfo_t *tap_id_base)
2782 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_mgcp_));
2785 /****************************************************************************/
2786 /****************************TAP for ACTRACE (AudioCodes trace)**************/
2787 /****************************************************************************/
2789 /* whenever a ACTRACE packet is seen by the tap listener */
2791 actrace_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *ACTRACEinfo)
2793 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_actrace_);
2794 const actrace_info_t *pi = (const actrace_info_t *)ACTRACEinfo;
2796 actrace_cas_calls_info_t *tmp_actrace_cas_info;
2797 voip_calls_info_t *tmp_listinfo;
2798 voip_calls_info_t *callsinfo = NULL;
2800 tapinfo->actrace_frame_num = pinfo->num;
2801 tapinfo->actrace_trunk = pi->trunk;
2802 tapinfo->actrace_direction = pi->direction;
2804 if (pi->type == 1) { /* is CAS protocol */
2806 gchar *comment = NULL;
2809 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
2812 tmp_listinfo=(voip_calls_info_t *)list->data;
2813 if ( tmp_listinfo->protocol == VOIP_AC_CAS ) {
2814 tmp_actrace_cas_info = (actrace_cas_calls_info_t *)tmp_listinfo->prot_info;
2815 /* TODO: Also check the IP of the Blade, and if the call is complete (no active) */
2816 if ( (tmp_actrace_cas_info->bchannel == pi->cas_bchannel) && (tmp_actrace_cas_info->trunk == tapinfo->actrace_trunk) ) {
2817 callsinfo = (voip_calls_info_t*)(list->data);
2821 list = g_list_next (list);
2824 set_address(&pstn_add, AT_STRINGZ, 5, "PSTN");
2826 /* if it is a new call, add it to the list */
2828 callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
2829 callsinfo->call_active_state = VOIP_ACTIVE;
2830 callsinfo->call_state = VOIP_CALL_SETUP;
2831 callsinfo->from_identity=g_strdup("N/A");
2832 callsinfo->to_identity=g_strdup("N/A");
2833 copy_address(&(callsinfo->initial_speaker),tapinfo->actrace_direction?&pstn_add:&(pinfo->src));
2834 callsinfo->selected=FALSE;
2835 callsinfo->start_fd=pinfo->fd;
2836 callsinfo->start_rel_ts=pinfo->rel_ts;
2837 callsinfo->protocol=VOIP_AC_CAS;
2838 callsinfo->prot_info=g_malloc(sizeof(actrace_cas_calls_info_t));
2839 callsinfo->free_prot_info = g_free;
2841 tmp_actrace_cas_info=(actrace_cas_calls_info_t *)callsinfo->prot_info;
2842 tmp_actrace_cas_info->bchannel=pi->cas_bchannel;
2843 tmp_actrace_cas_info->trunk=tapinfo->actrace_trunk;
2844 callsinfo->npackets = 0;
2845 callsinfo->call_num = tapinfo->ncalls++;
2846 g_queue_push_tail(tapinfo->callsinfos, callsinfo);
2849 callsinfo->stop_fd = pinfo->fd;
2850 callsinfo->stop_rel_ts = pinfo->rel_ts;
2851 ++(callsinfo->npackets);
2852 /* increment the packets counter of all calls */
2853 ++(tapinfo->npackets);
2855 comment = g_strdup_printf("AC_CAS trunk:%u", tapinfo->actrace_trunk);
2857 add_to_graph(tapinfo, pinfo, edt, pi->cas_frame_label, comment, callsinfo->call_num,
2858 tapinfo->actrace_direction?&pstn_add:&(pinfo->src),
2859 tapinfo->actrace_direction?&(pinfo->src):&pstn_add,
2865 tapinfo->redraw |= REDRAW_ACTRACE;
2867 return TRUE; /* refresh output */
2870 /****************************************************************************/
2872 actrace_calls_draw(void *tap_offset_ptr)
2874 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_actrace_);
2876 if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_ACTRACE)) {
2877 tapinfo->tap_draw(tapinfo);
2878 tapinfo->redraw &= ~REDRAW_ACTRACE;
2882 /****************************************************************************/
2884 /****************************************************************************/
2886 actrace_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
2888 GString *error_string;
2890 error_string = register_tap_listener("actrace", tap_base_to_id(tap_id_base, tap_id_offset_actrace_), NULL,
2893 actrace_calls_packet,
2897 if (error_string != NULL) {
2898 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2899 "%s", error_string->str);
2900 g_string_free(error_string, TRUE);
2904 /****************************************************************************/
2906 remove_tap_listener_actrace_calls(voip_calls_tapinfo_t *tap_id_base)
2908 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_actrace_));
2912 /****************************************************************************/
2913 /**************************** TAP for H248/MEGACO **********************************/
2914 /****************************************************************************/
2916 #define gcp_is_req(type) ( type == GCP_CMD_ADD_REQ || type == GCP_CMD_MOVE_REQ || type == GCP_CMD_MOD_REQ || \
2917 type == GCP_CMD_SUB_REQ || type == GCP_CMD_AUDITCAP_REQ || type == GCP_CMD_AUDITVAL_REQ || \
2918 type == GCP_CMD_NOTIFY_REQ || type == GCP_CMD_SVCCHG_REQ || type == GCP_CMD_TOPOLOGY_REQ || \
2919 type == GCP_CMD_CTX_ATTR_AUDIT_REQ )
2923 h248_calls_packet_common(voip_calls_tapinfo_t *tapinfo, packet_info *pinfo, epan_dissect_t *edt, const void *prot_info, guint32 redraw_bit) {
2924 const gcp_cmd_t *cmd = (const gcp_cmd_t *)prot_info;
2926 voip_calls_info_t *callsinfo = NULL;
2929 gchar mgw_addr[128];
2931 if (cmd->ctx->id == NULL_CONTEXT || cmd->ctx->id == ALL_CONTEXTS ) {
2935 if ( gcp_is_req(cmd->type) ) {
2936 mgw = &(pinfo->dst);
2937 mgc = &(pinfo->src);
2939 mgc = &(pinfo->dst);
2940 mgw = &(pinfo->src);
2943 address_to_str_buf(mgw, mgw_addr, 128);
2945 /* check whether we already have this context in the list */
2946 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
2949 voip_calls_info_t* tmp_listinfo = (voip_calls_info_t *)list->data;
2951 if (tmp_listinfo->protocol == TEL_H248) {
2952 if (tmp_listinfo->prot_info == cmd->ctx) {
2953 callsinfo = (voip_calls_info_t*)(list->data);
2957 list = g_list_next (list);
2960 if (callsinfo==NULL) {
2962 callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
2963 callsinfo->call_state = VOIP_NO_STATE;
2964 callsinfo->call_active_state = VOIP_ACTIVE;
2965 callsinfo->from_identity = g_strdup_printf("%s : %.8x", mgw_addr, cmd->ctx->id);
2966 callsinfo->to_identity = g_strdup("");
2967 callsinfo->prot_info = cmd->ctx;
2968 callsinfo->free_prot_info = NULL;
2970 callsinfo->npackets = 1;
2972 copy_address(&(callsinfo->initial_speaker), mgc);
2974 callsinfo->protocol = TEL_H248;
2975 callsinfo->call_num = tapinfo->ncalls++;
2976 callsinfo->start_fd = pinfo->fd;
2977 callsinfo->start_rel_ts = pinfo->rel_ts;
2978 callsinfo->stop_fd = pinfo->fd;
2979 callsinfo->stop_rel_ts = pinfo->rel_ts;
2981 callsinfo->selected = FALSE;
2983 g_queue_push_tail(tapinfo->callsinfos, callsinfo);
2986 GString *s = g_string_new("");
2987 gcp_terms_t *ctx_term;
2989 g_free(callsinfo->from_identity);
2990 callsinfo->from_identity = g_strdup_printf("%s : %.8x", mgw_addr, ((gcp_ctx_t*)callsinfo->prot_info)->id);
2992 g_free(callsinfo->to_identity);
2994 for (ctx_term = ((gcp_ctx_t*)callsinfo->prot_info)->terms.next;
2996 ctx_term = ctx_term->next ) {
2997 if ( ctx_term->term && ctx_term->term->str) {
2998 g_string_append_printf(s," %s",ctx_term->term->str);
3002 callsinfo->to_identity = g_string_free(s,FALSE);
3004 callsinfo->stop_fd = pinfo->fd;
3005 callsinfo->stop_rel_ts = pinfo->rel_ts;
3006 ++(callsinfo->npackets);
3009 add_to_graph(tapinfo, pinfo, edt, cmd->str ? cmd->str : "unknown Msg",
3010 wmem_strdup_printf(wmem_packet_scope(), "TrxId = %u, CtxId = %.8x",cmd->trx->id,cmd->ctx->id),
3011 callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3013 ++(tapinfo->npackets);
3015 tapinfo->redraw |= redraw_bit;
3021 h248_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *prot_info) {
3022 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_h248_);
3024 return h248_calls_packet_common(tapinfo, pinfo, edt, prot_info, REDRAW_H248);
3028 h248_calls_draw(void *tap_offset_ptr)
3030 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_h248_);
3032 if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_H248)) {
3033 tapinfo->tap_draw(tapinfo);
3034 tapinfo->redraw &= ~REDRAW_H248;
3039 megaco_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *prot_info) {
3040 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_megaco_);
3042 return h248_calls_packet_common(tapinfo, pinfo, edt, prot_info, REDRAW_MEGACO);
3046 megaco_calls_draw(void *tap_offset_ptr)
3048 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_megaco_);
3050 if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_MEGACO)) {
3051 tapinfo->tap_draw(tapinfo);
3052 tapinfo->redraw &= ~REDRAW_MEGACO;
3057 h248_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
3059 GString *error_string;
3061 error_string = register_tap_listener("megaco", tap_base_to_id(tap_id_base, tap_id_offset_megaco_),
3065 megaco_calls_packet,
3068 if (error_string != NULL) {
3069 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3070 "%s", error_string->str);
3071 g_string_free(error_string, TRUE);
3074 error_string = register_tap_listener("h248", tap_base_to_id(tap_id_base, tap_id_offset_h248_),
3081 if (error_string != NULL) {
3082 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3083 "%s", error_string->str);
3084 g_string_free(error_string, TRUE);
3089 remove_tap_listener_h248_calls(voip_calls_tapinfo_t *tap_id_base)
3091 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_h248_));
3092 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_megaco_));
3095 /****************************************************************************/
3096 /**************************** TAP for SCCP and SUA **********************************/
3097 /**************************** ( RANAP and BSSAP ) **********************************/
3098 /****************************************************************************/
3100 static const voip_protocol sccp_proto_map[] = {
3105 #define SP2VP(ap) ((ap) < SCCP_PLOAD_NUM_PLOADS ? sccp_proto_map[(ap)] : TEL_SCCP)
3106 const value_string* sccp_payload_values;
3109 sccp_calls(voip_calls_tapinfo_t *tapinfo, packet_info *pinfo, epan_dissect_t *edt, const void *prot_info, guint32 redraw_bit) {
3110 const sccp_msg_info_t* msg = (const sccp_msg_info_t *)prot_info;
3111 sccp_assoc_info_t* assoc = msg->data.co.assoc;
3113 voip_calls_info_t *callsinfo = NULL;
3114 gchar *label = NULL;
3115 const gchar *comment = NULL;
3116 /* check whether we already have this assoc in the list */
3118 for(list = g_queue_peek_nth_link(tapinfo->callsinfos, 0) ; list ; list = g_list_next (list) ) {
3119 if ( ((voip_calls_info_t*)(list->data))->prot_info == assoc ) {
3120 callsinfo = (voip_calls_info_t*)(list->data);
3125 if (callsinfo==NULL) {
3126 callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
3127 callsinfo->call_state = VOIP_CALL_SETUP;
3128 callsinfo->call_active_state = VOIP_ACTIVE;
3129 if ( assoc->calling_party ) {
3130 callsinfo->from_identity = g_strdup(assoc->calling_party);
3132 callsinfo->from_identity = g_strdup("Unknown");
3135 if ( assoc->called_party ) {
3136 callsinfo->to_identity = g_strdup(assoc->called_party);
3138 callsinfo->to_identity = g_strdup("Unknown");
3141 callsinfo->prot_info = (void*)assoc;
3142 callsinfo->free_prot_info = NULL;
3144 callsinfo->npackets = 1;
3146 copy_address(&(callsinfo->initial_speaker), &(pinfo->src));
3148 callsinfo->protocol = SP2VP(assoc->payload);
3149 /* Store frame data which holds time and frame number */
3150 callsinfo->start_fd = pinfo->fd;
3151 callsinfo->start_rel_ts = pinfo->rel_ts;
3152 callsinfo->stop_fd = pinfo->fd;
3153 callsinfo->stop_rel_ts = pinfo->rel_ts;
3155 callsinfo->selected = FALSE;
3156 callsinfo->call_num = tapinfo->ncalls++;
3158 g_queue_push_tail(tapinfo->callsinfos, callsinfo);
3161 if ( assoc->calling_party ) {
3162 g_free(callsinfo->from_identity);
3163 callsinfo->from_identity = g_strdup(assoc->calling_party);
3166 if ( assoc->called_party ) {
3167 g_free(callsinfo->to_identity);
3168 callsinfo->to_identity = g_strdup(assoc->called_party);
3171 callsinfo->protocol = SP2VP(assoc->payload);
3172 /* Store frame data which holds stop time and frame number */
3173 callsinfo->stop_fd = pinfo->fd;
3174 callsinfo->stop_rel_ts = pinfo->rel_ts;
3175 ++(callsinfo->npackets);
3177 switch (msg->type) {
3178 case SCCP_MSG_TYPE_CC:
3179 callsinfo->call_state = VOIP_IN_CALL;
3181 case SCCP_MSG_TYPE_RLC:
3182 callsinfo->call_state = VOIP_COMPLETED;
3183 callsinfo->call_active_state = VOIP_INACTIVE;
3190 if (msg->data.co.label) {
3191 label = wmem_strdup(NULL, msg->data.co.label);
3193 label = val_to_str_wmem(NULL, msg->type, sccp_payload_values, "Unknown(%d)");
3196 if (msg->data.co.comment) {
3197 comment = msg->data.co.comment;
3202 add_to_graph(tapinfo, pinfo, edt, label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3203 wmem_free(NULL, label);
3205 ++(tapinfo->npackets);
3207 tapinfo->redraw |= redraw_bit;
3213 sccp_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *prot_info) {
3214 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sccp_);
3216 sccp_payload_values = sccp_message_type_acro_values;
3217 return sccp_calls(tapinfo, pinfo, edt, prot_info, REDRAW_SCCP);
3221 sccp_calls_draw(void *tap_offset_ptr)
3223 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sccp_);
3225 if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_SCCP)) {
3226 tapinfo->tap_draw(tapinfo);
3227 tapinfo->redraw &= ~REDRAW_SCCP;
3232 sua_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *prot_info) {
3233 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sua_);
3235 sccp_payload_values = sua_co_class_type_acro_values;
3236 return sccp_calls(tapinfo, pinfo, edt, prot_info, REDRAW_SUA);
3240 sua_calls_draw(void *tap_offset_ptr)
3242 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sua_);
3244 if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_SUA)) {
3245 tapinfo->tap_draw(tapinfo);
3246 tapinfo->redraw &= ~REDRAW_SUA;
3250 void sccp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
3252 GString *error_string;
3254 error_string = register_tap_listener("sccp", tap_base_to_id(tap_id_base, tap_id_offset_sccp_),
3261 if (error_string != NULL) {
3262 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3263 "%s", error_string->str);
3264 g_string_free(error_string, TRUE);
3267 error_string = register_tap_listener("sua", tap_base_to_id(tap_id_base, tap_id_offset_sua_),
3274 if (error_string != NULL) {
3275 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3276 "%s", error_string->str);
3277 g_string_free(error_string, TRUE);
3282 remove_tap_listener_sccp_calls(voip_calls_tapinfo_t *tap_id_base)
3284 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_sccp_));
3285 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_sua_));
3289 /****************************************************************************/
3290 /****************************TAP for UNISTIM ********************************/
3291 /****************************************************************************/
3294 unistim_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *unistim_info)
3296 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_unistim_);
3297 voip_calls_info_t *tmp_listinfo;
3298 voip_calls_info_t *callsinfo = NULL;
3299 unistim_info_t *tmp_unistim_info = NULL;
3301 GString *g_tmp = NULL;
3302 const gchar *frame_label = NULL;
3303 gchar *comment = NULL;
3305 /* Fetch specific packet infos */
3306 const unistim_info_t *pi = (const unistim_info_t *)unistim_info;
3309 g_tmp = g_string_new(NULL);
3311 /* Check to see if this is a dup */
3312 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
3316 tmp_listinfo = (voip_calls_info_t *)list->data;
3318 if(tmp_listinfo->protocol == VOIP_UNISTIM) {
3320 tmp_unistim_info = (unistim_info_t *)tmp_listinfo->prot_info;
3322 /* Search by termid if possible, otherwise use ni/it ip + port.. */
3323 if(pi->termid != 0) {
3324 if(tmp_unistim_info->termid == pi->termid) {
3325 /* If the call has ended, then we can reuse it.. */
3326 if(tmp_listinfo->call_state == VOIP_COMPLETED || tmp_listinfo->call_state == VOIP_UNKNOWN) {
3329 callsinfo = (voip_calls_info_t*)(list->data);
3334 /* If no term id use ips / port to find entry */
3335 if(addresses_equal(&tmp_unistim_info->it_ip, &pinfo->dst) && addresses_equal(&tmp_unistim_info->ni_ip,&pinfo->src) && (tmp_unistim_info->it_port == pinfo->destport)) {
3336 if(tmp_listinfo->call_state == VOIP_COMPLETED || tmp_listinfo->call_state == VOIP_UNKNOWN) {
3337 /* Do nothing previous call */
3339 callsinfo = (voip_calls_info_t*)(list->data);
3343 else if(addresses_equal(&tmp_unistim_info->it_ip, &pinfo->src) && addresses_equal(&tmp_unistim_info->ni_ip,&pinfo->dst) && (tmp_unistim_info->it_port == pinfo->srcport)) {
3344 if(tmp_listinfo->call_state == VOIP_COMPLETED || tmp_listinfo->call_state == VOIP_UNKNOWN) {
3345 /* Do nothing, it ain't our call.. */
3347 callsinfo = (voip_calls_info_t*)(list->data);
3354 /* Otherwise, go to the next one.. */
3355 list = g_list_next(list);
3358 if(pi->payload_type == 2 || pi->payload_type == 1) {
3360 if(pi->key_state == 1 || pi->hook_state == 1) {
3362 /* If the user hits a button,
3363 Session will be SETUP */
3365 /* If new add to list */
3366 if (callsinfo==NULL) {
3368 callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
3369 callsinfo->call_active_state = VOIP_ACTIVE;
3370 callsinfo->call_state = VOIP_CALL_SETUP;
3371 callsinfo->from_identity=g_strdup_printf("%x",pi->termid);
3372 callsinfo->to_identity=g_strdup("UNKNOWN");
3373 copy_address(&(callsinfo->initial_speaker),&(pinfo->src));
3374 callsinfo->selected=FALSE;
3376 /* Set this on init of struct so in case the call doesn't complete, we'll have a ref. */
3377 /* Otherwise if the call is completed we'll have the open/close streams to ref actual call duration */
3378 /* Store frame data which holds time and frame number */
3379 callsinfo->start_fd=pinfo->fd;
3380 callsinfo->start_rel_ts=pinfo->rel_ts;
3382 callsinfo->protocol=VOIP_UNISTIM;
3383 callsinfo->prot_info=g_malloc(sizeof(unistim_info_t));
3385 tmp_unistim_info = (unistim_info_t *)callsinfo->prot_info;
3387 /* Clear tap struct */
3388 tmp_unistim_info->rudp_type = 0;
3389 tmp_unistim_info->payload_type = 0;
3390 tmp_unistim_info->sequence = pi->sequence;
3391 tmp_unistim_info->termid = pi->termid;
3392 tmp_unistim_info->key_val = -1;
3393 tmp_unistim_info->key_state = -1;
3394 tmp_unistim_info->hook_state = -1;
3395 tmp_unistim_info->stream_connect = -1;
3396 tmp_unistim_info->trans_connect = -1;
3397 tmp_unistim_info->set_termid = -1;
3398 tmp_unistim_info->string_data = NULL;
3399 tmp_unistim_info->key_buffer = NULL;
3401 copy_address(&(tmp_unistim_info->it_ip),&(pi->it_ip));
3402 copy_address(&(tmp_unistim_info->ni_ip),&(pi->ni_ip));
3403 tmp_unistim_info->it_port = pi->it_port;
3405 callsinfo->free_prot_info = g_free;
3406 callsinfo->npackets = 0;
3407 callsinfo->call_num = tapinfo->ncalls++;
3408 g_queue_push_tail(tapinfo->callsinfos, callsinfo);
3412 /* Set up call wide info struct */
3413 tmp_unistim_info = (unistim_info_t *)callsinfo->prot_info;
3414 tmp_unistim_info->sequence = pi->sequence;
3417 /* Each packet COULD BE OUR LAST!!!! */
3418 /* Store frame data which holds time and frame number */
3419 callsinfo->stop_fd = pinfo->fd;
3420 callsinfo->stop_rel_ts = pinfo->rel_ts;
3422 /* This is a valid packet so increment counter */
3423 ++(callsinfo->npackets);
3425 /* increment the packets counter of all calls */
3426 ++(tapinfo->npackets);
3428 /* Key was depressed.. update key buffer.. */
3429 if(pi->key_val >= 0 && pi->key_val <= 11) {
3431 if(tmp_unistim_info->key_buffer != NULL) {
3433 /* assign to temp variable */
3434 g_string_assign(g_tmp,tmp_unistim_info->key_buffer);
3436 /* Manipulate the data */
3437 if(pi->key_val == 10) {
3438 tmp_unistim_info->key_buffer = g_strdup_printf("%s*",g_tmp->str);
3439 } else if(pi->key_val == 11) {
3440 tmp_unistim_info->key_buffer = g_strdup_printf("%s#",g_tmp->str);
3442 tmp_unistim_info->key_buffer = g_strdup_printf("%s%d",g_tmp->str,pi->key_val);
3447 /* Create new string */
3448 if(pi->key_val == 10) {
3449 tmp_unistim_info->key_buffer = g_strdup("*");
3450 } else if(pi->key_val == 11) {
3451 tmp_unistim_info->key_buffer = g_strdup("#");
3453 tmp_unistim_info->key_buffer = g_strdup_printf("%d",pi->key_val);
3458 /* Select for non-digit characters */
3459 if(pi->key_val == 10) {
3460 comment = g_strdup_printf("Key Input Sent: * (%d)", pi->sequence);
3461 } else if(pi->key_val == 11) {
3462 comment = g_strdup_printf("Key Input Sent: # (%d)", pi->sequence);
3464 comment = g_strdup_printf("Key Input Sent: %d (%d)",pi->key_val, pi->sequence);
3466 } else if(pi->key_val == 12) {
3467 /* Set label and comment for graph */
3468 comment = g_strdup_printf("Key Input Sent: UP (%d)", pi->sequence);
3469 } else if(pi->key_val == 13) {
3470 /* Set label and comment for graph */
3471 comment = g_strdup_printf("Key Input Sent: DOWN (%d)", pi->sequence);
3472 } else if(pi->key_val == 14) {
3473 /* Set label and comment for graph */
3474 comment = g_strdup_printf("Key Input Sent: RIGHT (%d)", pi->sequence);
3475 } else if(pi->key_val == 15) {
3476 if(pi->key_buffer != NULL) {
3478 g_string_assign(g_tmp,pi->key_buffer);
3480 /* Manipulate the data */
3481 g_string_truncate(g_tmp,g_tmp->len-1);
3483 /* Insert new data */
3484 tmp_unistim_info->key_buffer = g_strdup(g_tmp->str);
3487 /* Set label and comment for graph */
3488 comment = g_strdup_printf("Key Input Sent: LEFT (%d)", pi->sequence);
3489 } else if(pi->key_val == 20) {
3490 /* User pressed the soft key 0 probably dial */
3491 comment = g_strdup_printf("Key Input Sent: S0 (%d)", pi->sequence);
3492 } else if(pi->key_val == 21) {
3493 /* User pressed the soft key 1 */
3494 comment = g_strdup_printf("Key Input Sent: S1 (%d)", pi->sequence);
3495 } else if(pi->key_val == 22) {
3496 /* User pressed the soft key 2 */
3497 /* On cs2k phones, soft key 2 is backspace. */
3498 if(pi->key_buffer != NULL) {
3501 g_string_assign(g_tmp,pi->key_buffer);
3503 /* Manipulate the data */
3504 g_string_truncate(g_tmp,g_tmp->len-1);
3506 /* Insert new data */
3507 tmp_unistim_info->key_buffer = g_strdup(g_tmp->str);
3510 /* add label and comment */
3511 comment = g_strdup_printf("Key Input Sent: S2 (%d)", pi->sequence);
3512 } else if(pi->key_val == 28) {
3513 /* User pressed something */
3514 comment = g_strdup_printf("Key Input Sent: Release (%d)", pi->sequence);
3515 } else if(pi->key_val == 23) {
3516 /* User pressed the soft key 3 */
3517 /* Cancel on cs2k so clear buffer */
3518 /* On mcs it's config which will clear the buffer too */
3519 tmp_unistim_info->key_buffer = g_strdup("\n");
3521 /* User pressed something, set labels*/
3522 comment = g_strdup_printf("Key Input Sent: S3 (%d)", pi->sequence);
3523 } else if(pi->key_val == 27) {
3524 /* User pressed something */
3525 comment = g_strdup_printf("Key Input Sent: Hold (%d)", pi->sequence);
3526 } else if(pi->key_val == 29) {
3527 /* User pressed something */
3528 comment = g_strdup_printf("Key Input Sent: Mute (%d)", pi->sequence);
3529 } else if(pi->key_val == 30) {
3530 /* User pressed something */
3531 comment = g_strdup_printf("Key Input Sent: Headset (%d)", pi->sequence);
3532 } else if(pi->key_val == 31) {
3533 /* Handsfree button */
3534 comment = g_strdup_printf("Key Input Sent: Handsfree (%d)", pi->sequence);
3535 } else if(pi->key_val >= 32 && pi->key_val <= 56) {
3537 comment = g_strdup_printf("Key Input Sent: Prog%d (%d)", (pi->key_val & 31), pi->sequence);
3540 if(pi->key_val != -1) {
3542 frame_label = "KEY INPUT";
3544 if (comment == NULL)
3545 /* Ouch! What do you do!? */
3546 /* User pressed something */
3547 comment = g_strdup_printf("Key Input Sent: UNKNOWN - %d (%d)", pi->key_val, pi->sequence);
3549 /* add to the graph */
3550 add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3555 if(pi->hook_state == 1) {
3557 /* Phone is off hook */
3558 frame_label = "OFF HOOK";
3559 comment = g_strdup_printf("Off Hook (%d)", pi->sequence);
3561 /* add to the graph */
3562 add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3565 } else if(pi->hook_state == 0) {
3567 /* Phone is on hook */
3568 frame_label = "ON HOOK";
3569 comment = g_strdup_printf("On Hook (%d)", pi->sequence);
3571 /* add to the graph */
3572 add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3578 /* Open stream was sent from server */
3579 if(pi->stream_connect == 1 && callsinfo != NULL) {
3582 /* Signifies the start of the call so set start_sec & start_usec */
3583 /* Frame data holds the time info */
3584 callsinfo->start_fd=pinfo->fd;
3585 callsinfo->start_rel_ts=pinfo->rel_ts;
3586 /* Each packet COULD BE OUR LAST!!!! */
3587 /* Store frame data which holds time and frame number */
3588 callsinfo->stop_fd = pinfo->fd;
3589 callsinfo->stop_rel_ts = pinfo->rel_ts;
3591 /* Local packets too */
3592 ++(callsinfo->npackets);
3594 /* increment the packets counter of all calls */
3595 ++(tapinfo->npackets);
3597 /* ?? means we're not quite sure if this is accurate. Since Unistim isn't a true
3598 Call control protocol, we can only guess at the destination by messing with
3600 if(tmp_unistim_info->key_buffer != NULL) {
3601 callsinfo->to_identity = g_strdup_printf("?? %s",tmp_unistim_info->key_buffer);
3604 /* change sequence number for ACK detection */
3605 tmp_unistim_info->sequence = pi->sequence;
3607 /* State changes too */
3608 callsinfo->call_active_state = VOIP_ACTIVE;
3609 callsinfo->call_state = VOIP_IN_CALL;
3611 /* Add graph data */
3612 frame_label = "STREAM OPENED";
3613 comment = g_strdup_printf("Stream Opened (%d)",pi->sequence);
3615 /* add to the graph */
3616 add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3618 } else if(pi->stream_connect == 1 && callsinfo == NULL) {
3620 /* Research indicates some nortel products initiate stream first
3621 * without keypresses. therefore creating this solely on a keypress is
3623 * Sometimes calls start immediately with open stream.
3625 callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
3626 callsinfo->call_active_state = VOIP_ACTIVE;
3627 callsinfo->call_state = VOIP_CALL_SETUP;
3628 callsinfo->from_identity=g_strdup("UNKNOWN");
3629 callsinfo->to_identity=g_strdup("UNKNOWN");
3630 copy_address(&(callsinfo->initial_speaker),&(pinfo->src));
3631 callsinfo->selected=FALSE;
3633 /* Set this on init of struct so in case the call doesn't complete, we'll have a ref. */
3634 /* Otherwise if the call is completed we'll have the open/close streams to ref actual call duration */
3635 callsinfo->start_fd=pinfo->fd;
3636 callsinfo->start_rel_ts=pinfo->rel_ts;
3638 callsinfo->protocol=VOIP_UNISTIM;
3639 callsinfo->prot_info=g_malloc(sizeof(unistim_info_t));
3641 tmp_unistim_info = (unistim_info_t *)callsinfo->prot_info;
3643 /* Clear tap struct */
3644 tmp_unistim_info->rudp_type = 0;
3645 tmp_unistim_info->payload_type = 0;
3646 tmp_unistim_info->sequence = pi->sequence;
3647 tmp_unistim_info->termid = 0;
3648 tmp_unistim_info->key_val = -1;
3649 tmp_unistim_info->key_state = -1;
3650 tmp_unistim_info->hook_state = -1;
3651 tmp_unistim_info->stream_connect = -1;
3652 tmp_unistim_info->trans_connect = -1;
3653 tmp_unistim_info->set_termid = -1;
3654 tmp_unistim_info->string_data = NULL;
3655 tmp_unistim_info->key_buffer = NULL;
3657 copy_address(&(tmp_unistim_info->it_ip),&(pi->it_ip));
3658 copy_address(&(tmp_unistim_info->ni_ip),&(pi->ni_ip));
3659 tmp_unistim_info->it_port = pi->it_port;
3661 callsinfo->free_prot_info = g_free;
3662 callsinfo->npackets = 0;
3663 callsinfo->call_num = tapinfo->ncalls++;
3664 g_queue_push_tail(tapinfo->callsinfos, callsinfo);
3667 /* Each packet COULD BE OUR LAST!!!! */
3668 /* Store frame data which holds time and frame number */
3669 callsinfo->stop_fd = pinfo->fd;
3670 callsinfo->stop_rel_ts = pinfo->rel_ts;
3671 /* Local packets too */
3672 ++(callsinfo->npackets);
3674 /* increment the packets counter of all calls */
3675 ++(tapinfo->npackets);
3677 /* ?? means we're not quite sure if this is accurate. Since Unistim isn't a true
3678 Call control protocol, we can only guess at the destination by messing with
3680 if(tmp_unistim_info->key_buffer != NULL) {
3681 callsinfo->to_identity = g_strdup_printf("?? %s",tmp_unistim_info->key_buffer);
3684 /* change sequence number for ACK detection */
3685 tmp_unistim_info->sequence = pi->sequence;
3687 /* State changes too */
3688 callsinfo->call_active_state = VOIP_ACTIVE;
3689 callsinfo->call_state = VOIP_IN_CALL;
3691 /* Add graph data */
3692 frame_label = "STREAM OPENED";
3693 comment = g_strdup_printf("Stream Opened (%d)",pi->sequence);
3695 /* add to the graph */
3696 add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3698 } else if(pi->stream_connect == 0 && callsinfo != NULL) {
3701 /* Set stop seconds + usec */
3702 /* frame_data holds the time info */
3703 callsinfo->stop_fd = pinfo->fd;
3704 callsinfo->stop_rel_ts = pinfo->rel_ts;
3706 tmp_unistim_info->sequence = pi->sequence;
3708 if(callsinfo->call_state == VOIP_IN_CALL) {
3709 callsinfo->call_active_state = VOIP_INACTIVE;
3710 callsinfo->call_state = VOIP_COMPLETED;
3712 callsinfo->call_state = VOIP_UNKNOWN;
3713 callsinfo->call_active_state = VOIP_INACTIVE;
3716 frame_label = "STREAM CLOSED";
3717 comment = g_strdup_printf("Stream Closed (%d)",pi->sequence);
3719 /* add to the graph */
3720 add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3725 } else if(pi->rudp_type == 1 && callsinfo != NULL) {
3727 /* Only show acks for processed seq #s */
3728 if(tmp_unistim_info->sequence == pi->sequence) {
3730 frame_label = "ACK";
3731 comment = g_strdup_printf("ACK for sequence %d",pi->sequence);
3733 /* add to the graph */
3734 add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3738 } else if(pi->rudp_type == 0 && callsinfo != NULL) {
3741 frame_label = "NAK";
3742 comment = g_strdup_printf("NAK for sequence %d",pi->sequence);
3744 /* add to the graph */
3745 add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3752 tapinfo->redraw |= REDRAW_UNISTIM;
3757 /****************************************************************************/
3759 unistim_calls_draw(void *tap_offset_ptr)
3761 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_unistim_);
3763 if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_UNISTIM)) {
3764 tapinfo->tap_draw(tapinfo);
3765 tapinfo->redraw &= ~REDRAW_UNISTIM;
3769 /****************************************************************************/
3771 /****************************************************************************/
3773 unistim_calls_init_tap(voip_calls_tapinfo_t *tap_id_base) {
3775 GString *error_string;
3777 error_string = register_tap_listener("unistim", tap_base_to_id(tap_id_base, tap_id_offset_unistim_),
3781 unistim_calls_packet,
3785 if (error_string != NULL) {
3786 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3787 "%s", error_string->str);
3788 g_string_free(error_string, TRUE);
3792 /****************************************************************************/
3794 remove_tap_listener_unistim_calls(voip_calls_tapinfo_t *tap_id_base)
3796 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_unistim_));
3799 /****************************************************************************/
3800 /* ***************************TAP for SKINNY **********************************/
3801 /****************************************************************************/
3803 /* Telecaster to tap-voip call state mapping */
3804 static const voip_call_state skinny_tap_voip_state[] = {
3823 skinny_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *skinny_info)
3825 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_skinny_);
3827 voip_calls_info_t *callsinfo = NULL;
3829 const skinny_info_t *si = (const skinny_info_t *)skinny_info;
3830 skinny_calls_info_t *tmp_skinnyinfo;
3833 if (si == NULL || (si->callId == 0 && si->passThruId == 0))
3835 /* check whether we already have this context in the list */
3836 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
3839 voip_calls_info_t* tmp_listinfo = (voip_calls_info_t *)list->data;
3840 if (tmp_listinfo->protocol == VOIP_SKINNY) {
3841 tmp_skinnyinfo = (skinny_calls_info_t *)tmp_listinfo->prot_info;
3842 if (tmp_skinnyinfo->callId == si->callId ||
3843 tmp_skinnyinfo->callId == si->passThruId) {
3844 callsinfo = (voip_calls_info_t*)(list->data);
3848 list = g_list_next (list);
3851 if (si->messId >= 256)
3852 phone = &(pinfo->dst);
3854 phone = &(pinfo->src);
3856 if (callsinfo==NULL) {
3857 callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
3858 callsinfo->call_state = VOIP_NO_STATE;
3859 callsinfo->call_active_state = VOIP_ACTIVE;
3860 /* callsinfo->from_identity = g_strdup_printf("%s : %.8x", "Skinny", 1); */
3861 callsinfo->from_identity = g_strdup("");
3862 callsinfo->to_identity = g_strdup("");
3863 callsinfo->prot_info = g_malloc(sizeof(skinny_calls_info_t));
3864 callsinfo->free_prot_info = g_free;
3865 tmp_skinnyinfo = (skinny_calls_info_t *)callsinfo->prot_info;
3866 tmp_skinnyinfo->callId = si->callId ? si->callId : si->passThruId;
3867 callsinfo->npackets = 1;
3869 copy_address(&(callsinfo->initial_speaker), phone);
3871 callsinfo->protocol = VOIP_SKINNY;
3872 callsinfo->call_num = tapinfo->ncalls++;
3873 callsinfo->start_fd = pinfo->fd;
3874 callsinfo->start_rel_ts = pinfo->rel_ts;
3875 callsinfo->stop_fd = pinfo->fd;
3876 callsinfo->stop_rel_ts = pinfo->rel_ts;
3878 callsinfo->selected = FALSE;
3879 g_queue_push_tail(tapinfo->callsinfos, callsinfo);
3881 if (si->callingParty) {
3882 g_free(callsinfo->from_identity);
3883 callsinfo->from_identity = g_strdup(si->callingParty);
3885 if (si->calledParty) {
3886 g_free(callsinfo->to_identity);
3887 callsinfo->to_identity = g_strdup(si->calledParty);
3889 if ((si->callState > 0) && (si->callState < (sizeof(skinny_tap_voip_state)/sizeof(skinny_tap_voip_state[0]))))
3890 callsinfo->call_state = skinny_tap_voip_state[si->callState];
3892 callsinfo->stop_fd = pinfo->fd;
3893 callsinfo->stop_rel_ts = pinfo->rel_ts;
3894 ++(callsinfo->npackets);
3899 comment = g_strdup_printf("CallId = %u, PTId = %u", si->callId, si->passThruId);
3901 comment = g_strdup_printf("CallId = %u, LineId = %u", si->callId, si->lineId);
3904 comment = g_strdup_printf("PTId = %u", si->passThruId);
3909 add_to_graph(tapinfo, pinfo, edt, si->messageName, comment,
3910 callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3913 tapinfo->redraw |= REDRAW_SKINNY;
3918 /****************************************************************************/
3920 skinny_calls_draw(void *tap_offset_ptr)
3922 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_skinny_);
3924 if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_SKINNY)) {
3925 tapinfo->tap_draw(tapinfo);
3926 tapinfo->redraw &= ~REDRAW_SKINNY;
3930 /****************************************************************************/
3932 /****************************************************************************/
3934 skinny_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
3936 GString *error_string;
3939 * We set TL_REQUIRES_PROTO_TREE to force a non-null "tree"
3940 * in the SKINNY dissector; otherwise, the dissector
3941 * doesn't fill in the info passed to the tap's packet
3944 error_string = register_tap_listener("skinny",
3945 tap_base_to_id(tap_id_base, tap_id_offset_skinny_),
3947 TL_REQUIRES_PROTO_TREE,
3949 skinny_calls_packet,
3952 if (error_string != NULL) {
3953 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3954 "%s", error_string->str);
3955 g_string_free(error_string, TRUE);
3959 /****************************************************************************/
3961 remove_tap_listener_skinny_calls(voip_calls_tapinfo_t *tap_id_base)
3963 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_skinny_));
3966 /****************************************************************************/
3967 /* ***************************TAP for IAX2 **********************************/
3968 /****************************************************************************/
3970 static void free_iax2_info(gpointer p) {
3971 iax2_info_t *ii = (iax2_info_t *)p;
3977 /****************************************************************************/
3978 /* whenever a IAX2 packet is seen by the tap listener */
3980 iax2_calls_packet( void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *iax2_info)
3982 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_iax2_);
3984 voip_calls_info_t *callsinfo = NULL;
3986 const iax2_info_t *ii = (const iax2_info_t *)iax2_info;
3987 iax2_info_t *tmp_iax2info;
3989 if (ii == NULL || ii->ptype != IAX2_FULL_PACKET || (ii->scallno == 0 && ii->dcallno == 0))
3991 /* check whether we already have this context in the list */
3992 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
3995 voip_calls_info_t* tmp_listinfo = (voip_calls_info_t *)list->data;
3996 if (tmp_listinfo->protocol == VOIP_IAX2) {
3997 tmp_iax2info = (iax2_info_t *)tmp_listinfo->prot_info;
3998 if (tmp_iax2info->scallno == ii->scallno ||
3999 tmp_iax2info->scallno == ii->dcallno) {
4000 callsinfo = (voip_calls_info_t*)(list->data);
4004 list = g_list_next (list);
4006 phone = &(pinfo->src);
4009 if (callsinfo==NULL) {
4010 /* We only care about real calls, i.e., no registration stuff */
4011 if (ii->ftype != AST_FRAME_IAX || ii->csub != IAX_COMMAND_NEW)
4013 callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
4014 callsinfo->call_state = VOIP_NO_STATE;
4015 callsinfo->call_active_state = VOIP_ACTIVE;
4016 callsinfo->prot_info=g_malloc(sizeof(iax2_info_t));
4017 callsinfo->free_prot_info = free_iax2_info;
4018 tmp_iax2info = (iax2_info_t *)callsinfo->prot_info;
4020 tmp_iax2info->scallno = ii->scallno;
4021 if (tmp_iax2info->scallno == 0) tmp_iax2info->scallno = ii->dcallno;
4022 tmp_iax2info->callState = ii->callState;
4024 callsinfo->npackets = 1;
4026 copy_address(&(callsinfo->initial_speaker), phone);
4027 callsinfo->from_identity = g_strdup(ii->callingParty);
4028 callsinfo->to_identity = g_strdup(ii->calledParty);
4030 callsinfo->protocol = VOIP_IAX2;
4031 callsinfo->call_num = tapinfo->ncalls++;
4032 callsinfo->start_fd=pinfo->fd;
4033 callsinfo->start_rel_ts=pinfo->rel_ts;
4034 callsinfo->stop_fd = pinfo->fd;
4035 callsinfo->stop_rel_ts = pinfo->rel_ts;
4037 callsinfo->selected = FALSE;
4038 g_queue_push_tail(tapinfo->callsinfos, callsinfo);
4041 callsinfo->call_state = ii->callState;
4043 callsinfo->stop_fd = pinfo->fd;
4044 callsinfo->stop_rel_ts = pinfo->rel_ts;
4045 ++(callsinfo->npackets);
4048 add_to_graph(tapinfo, pinfo, edt, ii->messageName, "",
4049 callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
4051 tapinfo->redraw |= REDRAW_IAX2;
4057 /****************************************************************************/
4059 iax2_calls_draw(void *tap_offset_ptr)
4061 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_iax2_);
4063 if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_IAX2)) {
4064 tapinfo->tap_draw(tapinfo);
4065 tapinfo->redraw &= ~REDRAW_IAX2;
4069 /****************************************************************************/
4071 /****************************************************************************/
4073 iax2_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
4075 GString *error_string;
4078 * We set TL_REQUIRES_PROTO_TREE to force a non-null "tree"
4079 * in the IAX2 dissector; otherwise, the dissector
4080 * doesn't fill in the info passed to the tap's packet
4082 * XXX - that appears to be true of the MGCP and SKINNY
4083 * dissectors, but, unless I've missed something, it doesn't
4084 * appear to be true of the IAX2 dissector.
4086 error_string = register_tap_listener("IAX2",
4087 tap_base_to_id(tap_id_base, tap_id_offset_iax2_),
4089 TL_REQUIRES_PROTO_TREE,
4094 if (error_string != NULL) {
4095 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s",
4097 g_string_free(error_string, TRUE);
4101 /****************************************************************************/
4103 remove_tap_listener_iax2_calls(voip_calls_tapinfo_t *tap_id_base)
4105 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_iax2_));
4108 /****************************************************************************/
4109 /* ***************************TAP for OTHER PROTOCOL **********************************/
4110 /****************************************************************************/
4112 /* voip_calls_packet and voip_calls_init_tap appear to be dead code. We don't have a "voip" tap. */
4114 voip_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *VoIPinfo)
4116 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_voip_);
4117 voip_calls_info_t *callsinfo = NULL;
4118 voip_calls_info_t *tmp_listinfo;
4120 const voip_packet_info_t *pi = (const voip_packet_info_t *)VoIPinfo;
4122 /* VOIP_CALLS_DEBUG("num %u", pinfo->num); */
4124 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
4126 tmp_listinfo = (voip_calls_info_t *)list->data;
4127 if ( tmp_listinfo->protocol == VOIP_COMMON ) {
4128 if (!strcmp(pi->call_id, tmp_listinfo->call_id)) {
4129 callsinfo = (voip_calls_info_t*)(list->data);
4133 list = g_list_next(list);
4136 if (callsinfo == NULL) {
4137 callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
4138 callsinfo->call_active_state = pi->call_active_state;
4139 callsinfo->call_state = pi->call_state;
4140 callsinfo->call_id=g_strdup((pi->call_id)?pi->call_id:"");
4141 callsinfo->from_identity = g_strdup((pi->from_identity)?pi->from_identity:"");
4142 callsinfo->to_identity = g_strdup((pi->to_identity)?pi->to_identity:"");
4143 copy_address(&(callsinfo->initial_speaker),&(pinfo->src));
4144 callsinfo->selected=FALSE;
4145 callsinfo->start_fd=pinfo->fd;
4146 callsinfo->start_rel_ts=pinfo->rel_ts;
4147 callsinfo->protocol=VOIP_COMMON;
4148 callsinfo->protocol_name=g_strdup((pi->protocol_name)?pi->protocol_name:"");
4149 callsinfo->call_comment=g_strdup((pi->call_comment)?pi->call_comment:"");
4150 callsinfo->prot_info=NULL;
4151 callsinfo->free_prot_info = NULL;
4153 callsinfo->call_num = tapinfo->ncalls++;
4154 callsinfo->npackets = 0;
4156 g_queue_push_tail(tapinfo->callsinfos, callsinfo);
4159 callsinfo->call_active_state = pi->call_active_state;
4160 if ((callsinfo->call_state != VOIP_COMPLETED) && (pi->call_state == VOIP_COMPLETED))
4161 tapinfo->completed_calls++;
4162 if (pi->call_state != VOIP_NO_STATE)
4163 callsinfo->call_state = pi->call_state;
4164 if (pi->call_comment) {
4165 g_free(callsinfo->call_comment);
4166 callsinfo->call_comment=g_strdup(pi->call_comment);
4168 callsinfo->stop_fd = pinfo->fd;
4169 callsinfo->stop_rel_ts = pinfo->rel_ts;
4170 ++(callsinfo->npackets);
4171 ++(tapinfo->npackets);
4173 /* add to the graph */
4174 add_to_graph(tapinfo, pinfo, edt, (pi->frame_label)?pi->frame_label:"VoIP msg", pi->frame_comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
4176 tapinfo->redraw |= REDRAW_VOIP;
4181 /****************************************************************************/
4183 voip_calls_draw(void *tap_offset_ptr)
4185 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_voip_);
4187 if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_VOIP)) {
4188 tapinfo->tap_draw(tapinfo);
4189 tapinfo->redraw &= ~REDRAW_VOIP;
4193 /****************************************************************************/
4196 voip_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
4198 GString *error_string;
4200 error_string = register_tap_listener("voip", tap_base_to_id(tap_id_base, tap_id_offset_voip_),
4208 if (error_string != NULL) {
4209 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4210 "%s", error_string->str);
4211 g_string_free(error_string, TRUE);
4215 /****************************************************************************/
4217 remove_tap_listener_voip_calls(voip_calls_tapinfo_t *tap_id_base)
4219 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_voip_));
4222 /****************************************************************************/
4223 /* ***************************TAP for OTHER PROTOCOL **********************************/
4224 /****************************************************************************/
4226 /****************************************************************************/
4227 /* whenever a prot_ packet is seen by the tap listener */
4230 prot_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt _U_, const void *prot_info _U_)
4232 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_prot_);
4233 if (callsinfo!=NULL) {
4234 callsinfo->stop_abs = pinfo->abs_ts;
4235 callsinfo->stop_rel = pinfo->rel_ts;
4236 callsinfo->last_frame_num=pinfo->num;
4237 ++(callsinfo->npackets);
4238 ++(tapinfo->npackets);
4241 tapinfo->redraw = REDRAW_PROT;
4246 /****************************************************************************/
4248 prot_calls_draw(void *tap_offset_ptr)
4250 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_prot_);
4252 if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_PROT)) {
4253 tapinfo->tap_draw(tapinfo);
4254 tapinfo->redraw &= ~REDRAW_PROT;
4258 /****************************************************************************/
4260 prot_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
4262 GString *error_string;
4264 error_string = register_tap_listener("prot_", tap_base_to_id(tap_id_base, tap_id_offset_prot_),
4272 if (error_string != NULL) {
4273 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4274 "%s", error_string->str);
4275 g_string_free(error_string, TRUE);
4279 /****************************************************************************/
4281 remove_tap_listener_prot__calls(voip_calls_tapinfo_t *tap_id_base)
4283 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_prot_));
4288 * Editor modelines - https://www.wireshark.org/tools/modelines.html
4293 * indent-tabs-mode: nil
4296 * ex: set shiftwidth=4 tabstop=8 expandtab:
4297 * :indentSize=4:tabSize=8:noTabs=true: