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/dissectors/packet-sip.h"
42 #include "epan/dissectors/packet-h225.h"
43 #include "epan/dissectors/packet-h245.h"
44 #include "epan/dissectors/packet-sdp.h"
45 #include "epan/dissectors/packet-mgcp.h"
46 #include "epan/dissectors/packet-actrace.h"
47 #include "epan/dissectors/packet-rtp.h"
48 #include "epan/dissectors/packet-rtp-events.h"
49 #include "epan/dissectors/packet-t38.h"
50 #include "epan/dissectors/packet-t30.h"
51 #include "epan/dissectors/packet-h248.h"
52 #include "epan/dissectors/packet-sccp.h"
53 #include "plugins/unistim/packet-unistim.h"
54 #include "epan/dissectors/packet-skinny.h"
55 #include "epan/dissectors/packet-iax2.h"
56 #include "epan/rtp_pt.h"
58 #include "ui/rtp_stream.h"
59 #include "ui/simple_dialog.h"
60 #include "ui/ui_util.h"
61 #include "ui/voip_calls.h"
63 #define DUMP_PTR1(p) printf("#=> %p\n",(void *)p)
64 #define DUMP_PTR2(p) printf("==> %p\n",(void *)p)
66 const char *voip_call_state_name[8]={
77 /* defines whether we can consider the call active */
78 const char *voip_protocol_name[]={
97 * Tap IDs must be unique. Since different taps need to share the
98 * same voip_calls_tapinfo_t *, make it unique by offsetting its
102 tap_id_offset_actrace_,
104 tap_id_offset_h245dg_,
109 tap_id_offset_megaco_,
114 tap_id_offset_rtp_event_,
118 tap_id_offset_skinny_,
121 tap_id_offset_unistim_,
126 tap_base_to_id(voip_calls_tapinfo_t* tap_base, int offset) {
127 return GSIZE_TO_POINTER(GPOINTER_TO_SIZE(tap_base) + offset);
130 static inline voip_calls_tapinfo_t *
131 tap_id_to_base(void* tap_id, int offset) {
132 return (voip_calls_tapinfo_t *) GSIZE_TO_POINTER(GPOINTER_TO_SIZE(tap_id) - offset);
142 typedef struct _h245_labels {
145 graph_str labels[H245_MAX];
148 static void actrace_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
149 static void h225_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
150 static void h245dg_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
151 static void h248_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
152 static void iax2_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
153 static void isup_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
154 static void mgcp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
155 static void mtp3_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
156 static void q931_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
157 static void rtp_event_init_tap(voip_calls_tapinfo_t *tap_id_base);
158 static void rtp_init_tap(voip_calls_tapinfo_t *tap_id_base);
159 static void sccp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
160 static void sdp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
161 static void sip_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
162 static void skinny_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
163 static void t38_init_tap(voip_calls_tapinfo_t *tap_id_base);
164 static void unistim_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
165 static void voip_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
168 voip_calls_init_all_taps(voip_calls_tapinfo_t *tap_id_base)
170 actrace_calls_init_tap(tap_id_base);
171 h225_calls_init_tap(tap_id_base);
172 h245dg_calls_init_tap(tap_id_base);
173 h248_calls_init_tap(tap_id_base);
174 iax2_calls_init_tap(tap_id_base);
175 isup_calls_init_tap(tap_id_base);
176 mgcp_calls_init_tap(tap_id_base);
177 mtp3_calls_init_tap(tap_id_base);
178 q931_calls_init_tap(tap_id_base);
179 rtp_event_init_tap(tap_id_base);
180 rtp_init_tap(tap_id_base); /* This calls tap_reset_cb, tap_packet_cb, and tap_draw_cb */
181 sccp_calls_init_tap(tap_id_base);
182 sdp_calls_init_tap(tap_id_base);
183 sip_calls_init_tap(tap_id_base);
184 skinny_calls_init_tap(tap_id_base);
185 t38_init_tap(tap_id_base);
186 /* We don't register this tap if we don't have the unistim plugin loaded.*/
187 if (find_tap_id("unistim")) {
188 unistim_calls_init_tap(tap_id_base);
190 if (find_tap_id("voip")) {
191 voip_calls_init_tap(tap_id_base);
195 static void remove_tap_listener_actrace_calls(voip_calls_tapinfo_t *tap_id_base);
196 static void remove_tap_listener_h225_calls(voip_calls_tapinfo_t *tap_id_base);
197 static void remove_tap_listener_h245dg_calls(voip_calls_tapinfo_t *tap_id_base);
198 static void remove_tap_listener_h248_calls(voip_calls_tapinfo_t *tap_id_base);
199 static void remove_tap_listener_iax2_calls(voip_calls_tapinfo_t *tap_id_base);
200 static void remove_tap_listener_isup_calls(voip_calls_tapinfo_t *tap_id_base);
201 static void remove_tap_listener_mgcp_calls(voip_calls_tapinfo_t *tap_id_base);
202 static void remove_tap_listener_mtp3_calls(voip_calls_tapinfo_t *tap_id_base);
203 static void remove_tap_listener_q931_calls(voip_calls_tapinfo_t *tap_id_base);
204 static void remove_tap_listener_rtp(voip_calls_tapinfo_t *tap_id_base);
205 static void remove_tap_listener_rtp_event(voip_calls_tapinfo_t *tap_id_base);
206 static void remove_tap_listener_sccp_calls(voip_calls_tapinfo_t *tap_id_base);
207 static void remove_tap_listener_sdp_calls(voip_calls_tapinfo_t *tap_id_base);
208 static void remove_tap_listener_sip_calls(voip_calls_tapinfo_t *tap_id_base);
209 static void remove_tap_listener_skinny_calls(voip_calls_tapinfo_t *tap_id_base);
210 static void remove_tap_listener_t38(voip_calls_tapinfo_t *tap_id_base);
211 static void remove_tap_listener_unistim_calls(voip_calls_tapinfo_t *tap_id_base);
212 static void remove_tap_listener_voip_calls(voip_calls_tapinfo_t *tap_id_base);
214 void voip_calls_remove_all_tap_listeners(voip_calls_tapinfo_t *tap_id_base)
216 /* Remove the calls tap listener */
217 remove_tap_listener_actrace_calls(tap_id_base);
218 remove_tap_listener_h225_calls(tap_id_base);
219 remove_tap_listener_h245dg_calls(tap_id_base);
220 remove_tap_listener_h248_calls(tap_id_base);
221 remove_tap_listener_iax2_calls(tap_id_base);
222 remove_tap_listener_isup_calls(tap_id_base);
223 remove_tap_listener_mgcp_calls(tap_id_base);
224 remove_tap_listener_mtp3_calls(tap_id_base);
225 remove_tap_listener_q931_calls(tap_id_base);
226 remove_tap_listener_rtp(tap_id_base);
227 remove_tap_listener_rtp_event(tap_id_base);
228 remove_tap_listener_sccp_calls(tap_id_base);
229 remove_tap_listener_sdp_calls(tap_id_base);
230 remove_tap_listener_sip_calls(tap_id_base);
231 remove_tap_listener_skinny_calls(tap_id_base);
232 remove_tap_listener_t38(tap_id_base);
233 if (find_tap_id("unistim")) { /* The plugin may be missing */
234 remove_tap_listener_unistim_calls(tap_id_base);
236 if (find_tap_id("voip")) {
237 remove_tap_listener_voip_calls(tap_id_base);
241 /****************************************************************************/
242 /* when there is a [re]reading of packet's */
244 voip_calls_reset_all_taps(voip_calls_tapinfo_t *tapinfo)
246 voip_calls_info_t *callsinfo;
247 rtp_stream_info_t *strinfo;
250 /* free the data items first */
251 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
254 callsinfo = (voip_calls_info_t *)list->data;
255 g_free(callsinfo->call_id);
256 g_free(callsinfo->from_identity);
257 g_free(callsinfo->to_identity);
258 g_free((void *)(callsinfo->initial_speaker.data));
259 g_free(callsinfo->protocol_name);
260 g_free(callsinfo->call_comment);
262 if (callsinfo->free_prot_info && callsinfo->prot_info)
263 callsinfo->free_prot_info(callsinfo->prot_info);
266 list = g_list_next(list);
268 g_queue_clear(tapinfo->callsinfos);
269 /* free the SIP_HASH */
270 if(NULL!=tapinfo->callsinfo_hashtable[SIP_HASH])
271 g_hash_table_remove_all (tapinfo->callsinfo_hashtable[SIP_HASH]);
273 /* free the graph data items first */
274 if(NULL == tapinfo->graph_analysis) {
275 tapinfo->graph_analysis = sequence_analysis_info_new();
278 sequence_analysis_list_free(tapinfo->graph_analysis);
280 /* free the strinfo data items first */
281 list = g_list_first(tapinfo->rtp_stream_list);
284 strinfo = (rtp_stream_info_t *)list->data;
285 wmem_free(NULL, strinfo->payload_type_name);
286 list = g_list_next(list);
288 g_list_free(tapinfo->rtp_stream_list);
289 tapinfo->rtp_stream_list = NULL;
291 if (!tapinfo->h245_labels) {
292 tapinfo->h245_labels = g_new0(h245_labels_t, 1);
294 memset(tapinfo->h245_labels, 0, sizeof(h245_labels_t));
300 /****************************************************************************/
301 /* Add a new item into the graph */
303 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)
305 seq_analysis_item_t *gai;
306 gchar time_str[COL_MAX_LEN];
308 if (!tapinfo->graph_analysis) {
312 gai = (seq_analysis_item_t *)g_malloc(sizeof(seq_analysis_item_t));
314 COPY_ADDRESS(&(gai->src_addr),src_addr);
315 COPY_ADDRESS(&(gai->dst_addr),dst_addr);
317 gai->port_src=pinfo->srcport;
318 gai->port_dst=pinfo->destport;
320 if (frame_label != NULL)
321 gai->frame_label = g_strdup(frame_label);
323 gai->frame_label = g_strdup("");
326 gai->comment = g_strdup(comment);
328 gai->comment = g_strdup("");
330 gai->conv_num=call_num;
331 gai->line_style=line_style;
332 set_fd_time(edt->session, gai->fd, time_str);
333 gai->time_str = g_strdup(time_str);
336 g_queue_push_tail(tapinfo->graph_analysis->items, gai);
337 g_hash_table_insert(tapinfo->graph_analysis->ht, &gai->fd->num, gai);
340 /****************************************************************************/
341 /* Append str to frame_label and comment in a graph item */
342 /* return 0 if the frame_num is not in the graph list */
343 static int append_to_frame_graph(voip_calls_tapinfo_t *tapinfo _U_, guint32 frame_num, const gchar *new_frame_label, const gchar *new_comment)
345 seq_analysis_item_t *gai=NULL;
346 gchar *frame_label = NULL;
347 gchar *comment = NULL;
349 if(tapinfo->graph_analysis && NULL!=tapinfo->graph_analysis->ht)
350 gai=(seq_analysis_item_t *)g_hash_table_lookup(tapinfo->graph_analysis->ht, &frame_num);
352 frame_label = gai->frame_label;
353 comment = gai->comment;
355 if (new_frame_label != NULL) {
356 gai->frame_label = g_strdup_printf("%s %s", frame_label, new_frame_label);
360 if (new_comment != NULL) {
361 gai->comment = g_strdup_printf("%s %s", comment, new_comment);
369 /****************************************************************************/
370 /* Change the frame_label and comment in a graph item if not NULL*/
371 /* return 0 if the frame_num is not in the graph list */
372 static int change_frame_graph(voip_calls_tapinfo_t *tapinfo _U_, guint32 frame_num, const gchar *new_frame_label, const gchar *new_comment)
374 seq_analysis_item_t *gai=NULL;
375 gchar *frame_label = NULL;
376 gchar *comment = NULL;
378 if(tapinfo->graph_analysis && NULL!=tapinfo->graph_analysis->ht)
379 gai=(seq_analysis_item_t *)g_hash_table_lookup(tapinfo->graph_analysis->ht, &frame_num);
381 frame_label = gai->frame_label;
382 comment = gai->comment;
384 if (new_frame_label != NULL) {
385 gai->frame_label = g_strdup(new_frame_label);
389 if (new_comment != NULL) {
390 gai->comment = g_strdup(new_comment);
398 /****************************************************************************/
399 /* Change all the graph items with call_num to new_call_num */
400 static guint change_call_num_graph(voip_calls_tapinfo_t *tapinfo _U_, guint16 call_num, guint16 new_call_num)
402 seq_analysis_item_t *gai;
407 if(tapinfo->graph_analysis){
408 list = g_queue_peek_nth_link(tapinfo->graph_analysis->items, 0);
411 gai = (seq_analysis_item_t *)list->data;
412 if (gai->conv_num == call_num) {
413 gai->conv_num = new_call_num;
416 list = g_list_next(list);
419 return items_changed;
422 /****************************************************************************/
423 /* Insert the item in the graph list */
424 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)
426 seq_analysis_item_t *gai, *new_gai;
430 gchar time_str[COL_MAX_LEN];
432 new_gai = (seq_analysis_item_t *)g_malloc(sizeof(seq_analysis_item_t));
433 new_gai->fd = packet_list_get_row_data(frame_num);
434 COPY_ADDRESS(&(new_gai->src_addr),src_addr);
435 COPY_ADDRESS(&(new_gai->dst_addr),dst_addr);
437 new_gai->port_src=pinfo->srcport;
438 new_gai->port_dst=pinfo->destport;
439 if (frame_label != NULL)
440 new_gai->frame_label = g_strdup(frame_label);
442 new_gai->frame_label = g_strdup("");
445 new_gai->comment = g_strdup(comment);
447 new_gai->comment = g_strdup("");
448 new_gai->conv_num=call_num;
449 new_gai->line_style=line_style;
450 set_fd_time(edt->session, new_gai->fd, time_str);
451 new_gai->time_str = g_strdup(time_str);
452 new_gai->display=FALSE;
456 if(tapinfo->graph_analysis){
457 list = g_queue_peek_nth_link(tapinfo->graph_analysis->items, 0);
460 gai = (seq_analysis_item_t *)list->data;
461 if (gai->fd->num > frame_num) {
462 g_queue_insert_before(tapinfo->graph_analysis->items, list, new_gai);
463 g_hash_table_insert(tapinfo->graph_analysis->ht, &new_gai->fd->num, new_gai);
467 list = g_list_next(list);
472 g_queue_push_tail(tapinfo->graph_analysis->items, new_gai);
473 g_hash_table_insert(tapinfo->graph_analysis->ht, &new_gai->fd->num, new_gai);
478 /****************************************************************************/
479 /* ***************************TAP for RTP Events*****************************/
480 /****************************************************************************/
482 /*static guint32 rtp_evt_setup_frame_num = 0;*/
484 /****************************************************************************/
485 /* whenever a rtp event packet is seen by the tap listener */
487 rtp_event_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt _U_, const void *rtp_event_info)
489 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_event_);
490 const struct _rtp_event_info *pi = (const struct _rtp_event_info *)rtp_event_info;
492 /* do not consider RTP events packets without a setup frame */
493 if (pi->info_setup_frame_num == 0) {
497 tapinfo->rtp_evt_frame_num = pinfo->fd->num;
498 tapinfo->rtp_evt = pi->info_rtp_evt;
499 tapinfo->rtp_evt_end = pi->info_end;
504 /****************************************************************************/
506 rtp_event_init_tap(voip_calls_tapinfo_t *tap_id_base)
508 GString *error_string;
510 error_string = register_tap_listener("rtpevent", tap_base_to_id(tap_id_base, tap_id_offset_rtp_event_),
518 if (error_string != NULL) {
519 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
520 "%s", error_string->str);
521 g_string_free(error_string, TRUE);
525 /****************************************************************************/
528 remove_tap_listener_rtp_event(voip_calls_tapinfo_t *tap_id_base)
530 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_rtp_event_));
533 /****************************************************************************/
534 /* ***************************TAP for RTP **********************************/
535 /****************************************************************************/
537 /****************************************************************************/
538 /* when there is a [re]reading of RTP packets */
540 rtp_reset(void *tap_offset_ptr)
542 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_);
545 /* free the data items first */
546 list = g_list_first(tapinfo->rtp_stream_list);
550 list = g_list_next(list);
552 g_list_free(tapinfo->rtp_stream_list);
553 tapinfo->rtp_stream_list = NULL;
554 tapinfo->nrtp_streams = 0;
556 if (tapinfo->tap_reset) {
557 tapinfo->tap_reset(tapinfo);
563 /****************************************************************************/
564 /* whenever a RTP packet is seen by the tap listener */
566 rtp_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, void const *rtp_info_ptr)
568 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_);
569 rtp_stream_info_t *tmp_listinfo;
570 rtp_stream_info_t *strinfo = NULL;
572 struct _rtp_conversation_info *p_conv_data = NULL;
574 const struct _rtp_info *rtp_info = (const struct _rtp_info *)rtp_info_ptr;
576 /* do not consider RTP packets without a setup frame */
577 if (rtp_info->info_setup_frame_num == 0) {
581 if (tapinfo->tap_packet) {
582 tapinfo->tap_packet(tapinfo, pinfo, edt, rtp_info_ptr);
585 /* check whether we already have a RTP stream with this setup frame and ssrc in the list */
586 list = g_list_first(tapinfo->rtp_stream_list);
589 tmp_listinfo=(rtp_stream_info_t *)list->data;
590 if ( (tmp_listinfo->setup_frame_number == rtp_info->info_setup_frame_num)
591 && (tmp_listinfo->ssrc == rtp_info->info_sync_src) && (tmp_listinfo->end_stream == FALSE)) {
592 /* if the payload type has changed, we mark the stream as finished to create a new one
593 this is to show multiple payload changes in the Graph for example for DTMF RFC2833 */
594 if ( tmp_listinfo->payload_type != rtp_info->info_payload_type ) {
595 tmp_listinfo->end_stream = TRUE;
597 strinfo = (rtp_stream_info_t*)(list->data);
601 list = g_list_next(list);
604 /* if this is a duplicated RTP Event End, just return */
605 if ((tapinfo->rtp_evt_frame_num == pinfo->fd->num) && !strinfo && (tapinfo->rtp_evt_end == TRUE)) {
609 /* not in the list? then create a new entry */
611 strinfo = (rtp_stream_info_t *)g_malloc(sizeof(rtp_stream_info_t));
612 COPY_ADDRESS(&(strinfo->src_addr), &(pinfo->src));
613 strinfo->src_port = pinfo->srcport;
614 COPY_ADDRESS(&(strinfo->dest_addr), &(pinfo->dst));
615 strinfo->dest_port = pinfo->destport;
616 strinfo->ssrc = rtp_info->info_sync_src;
617 strinfo->end_stream = FALSE;
618 strinfo->payload_type = rtp_info->info_payload_type;
619 strinfo->payload_type_name = NULL;
620 strinfo->is_srtp = rtp_info->info_is_srtp;
621 /* if it is dynamic payload, let use the conv data to see if it is defined */
622 if ( (strinfo->payload_type >= PT_UNDF_96) && (strinfo->payload_type <= PT_UNDF_127) ) {
623 /* Use existing packet info if available */
624 p_conv_data = (struct _rtp_conversation_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_get_id_by_filter_name("rtp"), 0);
625 if (p_conv_data && p_conv_data->rtp_dyn_payload) {
626 const gchar *encoding_name = rtp_dyn_payload_get_name(p_conv_data->rtp_dyn_payload, strinfo->payload_type);
628 strinfo->payload_type_name = wmem_strdup(NULL, encoding_name);
632 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");
633 strinfo->packet_count = 0;
634 strinfo->start_fd = pinfo->fd;
635 strinfo->start_rel_time = pinfo->rel_ts;
636 strinfo->setup_frame_number = rtp_info->info_setup_frame_num;
637 strinfo->rtp_event = -1;
638 tapinfo->rtp_stream_list = g_list_prepend(tapinfo->rtp_stream_list, strinfo);
641 /* Add the info to the existing RTP stream */
642 strinfo->packet_count++;
643 strinfo->stop_fd = pinfo->fd;
645 /* process RTP Event */
646 if (tapinfo->rtp_evt_frame_num == pinfo->fd->num) {
647 strinfo->rtp_event = tapinfo->rtp_evt;
648 if (tapinfo->rtp_evt_end == TRUE) {
649 strinfo->end_stream = TRUE;
653 tapinfo->redraw = TRUE;
658 /****************************************************************************/
659 /* whenever a redraw in the RTP tap listener */
661 rtp_draw(void *tap_offset_ptr)
663 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_);
664 GList *rtp_streams_list;
665 rtp_stream_info_t *rtp_listinfo;
666 /* GList *voip_calls_graph_list; */
667 seq_analysis_item_t *gai = NULL;
668 seq_analysis_item_t *new_gai;
671 gchar time_str[COL_MAX_LEN];
673 /* add each rtp stream to the graph */
674 rtp_streams_list = g_list_first(tapinfo->rtp_stream_list);
675 while (rtp_streams_list)
677 rtp_listinfo = (rtp_stream_info_t *)rtp_streams_list->data;
679 /* using the setup frame number of the RTP stream, we get the call number that it belongs to*/
680 /* voip_calls_graph_list = g_list_first(tapinfo->graph_analysis->list); */
681 if(tapinfo->graph_analysis){
682 gai = (seq_analysis_item_t *)g_hash_table_lookup(tapinfo->graph_analysis->ht, &rtp_listinfo->setup_frame_number);
685 const char *comment_fmt = "%s, %u packets. Duration: %u.%03us SSRC: 0x%X";
686 /* Found the setup frame*/
687 conv_num = gai->conv_num;
688 /* if RTP was already in the Graph, just update the comment information */
689 gai = (seq_analysis_item_t *)g_hash_table_lookup(tapinfo->graph_analysis->ht, &rtp_listinfo->start_fd->num);
691 duration = (guint32)(nstime_to_msec(&rtp_listinfo->stop_rel_time) - nstime_to_msec(&rtp_listinfo->start_rel_time));
692 g_free(gai->comment);
693 gai->comment = g_strdup_printf(comment_fmt,
694 (rtp_listinfo->is_srtp)?"SRTP":"RTP", rtp_listinfo->packet_count,
695 duration/1000,(duration%1000), rtp_listinfo->ssrc);
697 new_gai = (seq_analysis_item_t *)g_malloc(sizeof(seq_analysis_item_t));
698 new_gai->fd = rtp_listinfo->start_fd;
699 COPY_ADDRESS(&(new_gai->src_addr),&(rtp_listinfo->src_addr));
700 COPY_ADDRESS(&(new_gai->dst_addr),&(rtp_listinfo->dest_addr));
701 new_gai->port_src = rtp_listinfo->src_port;
702 new_gai->port_dst = rtp_listinfo->dest_port;
703 duration = (guint32)(nstime_to_msec(&rtp_listinfo->stop_rel_time) - nstime_to_msec(&rtp_listinfo->start_rel_time));
704 new_gai->frame_label = g_strdup_printf("%s (%s) %s",
705 (rtp_listinfo->is_srtp)?"SRTP":"RTP",
706 rtp_listinfo->payload_type_name,
707 (rtp_listinfo->rtp_event == -1)?
708 "":val_to_str_ext_const(rtp_listinfo->rtp_event, &rtp_event_type_values_ext, "Unknown RTP Event"));
709 new_gai->comment = g_strdup_printf(comment_fmt,
710 (rtp_listinfo->is_srtp)?"SRTP":"RTP", rtp_listinfo->packet_count,
711 duration/1000,(duration%1000), rtp_listinfo->ssrc);
712 new_gai->conv_num = conv_num;
713 set_fd_time(tapinfo->session, new_gai->fd, time_str);
714 new_gai->time_str = g_strdup(time_str);
715 new_gai->display=FALSE;
716 new_gai->line_style = 2; /* the arrow line will be 2 pixels width */
717 g_queue_push_tail(tapinfo->graph_analysis->items, new_gai);
718 g_hash_table_insert(tapinfo->graph_analysis->ht, &rtp_listinfo->start_fd, new_gai);
721 rtp_streams_list = g_list_next(rtp_streams_list);
722 } /* while (rtp_streams_list) */
724 if (tapinfo->tap_draw) {
725 tapinfo->tap_draw(tapinfo);
730 rtp_packet_draw(void *tap_offset_ptr)
732 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_);
733 GList *rtp_streams_list;
734 rtp_stream_info_t *rtp_listinfo;
735 GList *voip_calls_graph_list;
737 seq_analysis_item_t *gai;
738 seq_analysis_item_t *new_gai;
741 gchar time_str[COL_MAX_LEN];
743 /* add each rtp stream to the graph */
744 rtp_streams_list = g_list_first(tapinfo->stream_list);
745 while (rtp_streams_list)
747 rtp_listinfo = rtp_streams_list->data;
749 /* using the setup frame number of the RTP stream, we get the call number that it belongs to*/
750 voip_calls_graph_list = g_list_first(tapinfo->graph_analysis->list);
751 while (voip_calls_graph_list)
753 gai = voip_calls_graph_list->data;
754 conv_num = gai->conv_num;
755 /* if we get the setup frame number, then get the time position to graph the RTP arrow */
756 if (rtp_listinfo->setup_frame_number == gai->fd->num) {
757 /* look again from the beginning because there are cases where the Setup frame is after the RTP */
758 voip_calls_graph_list = g_list_first(tapinfo->graph_analysis->list);
760 while(voip_calls_graph_list) {
761 gai = voip_calls_graph_list->data;
762 /* if RTP was already in the Graph, just update the comment information */
763 if (rtp_listinfo->start_fd->num == gai->fd->num) {
764 duration = (guint32)(nstime_to_msec(&rtp_listinfo->stop_fd->rel_ts) - nstime_to_msec(&rtp_listinfo->start_fd->rel_ts));
765 g_free(gai->comment);
766 gai->comment = g_strdup_printf("%s Num packets:%u Duration:%u.%03us SSRC:0x%X",
767 (rtp_listinfo->is_srtp)?"SRTP":"RTP", rtp_listinfo->npackets,
768 duration/1000,(duration%1000), rtp_listinfo->ssrc);
772 /* 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 */
773 voip_calls_graph_list = g_list_next(voip_calls_graph_list);
774 if (!voip_calls_graph_list) item++;
776 /* add the RTP item to the graph if was not there*/
777 if (rtp_listinfo->start_fd->num<gai->fd->num || !voip_calls_graph_list) {
778 new_gai = g_malloc(sizeof(seq_analysis_item_t));
779 new_gai->fd = rtp_listinfo->start_fd;
780 COPY_ADDRESS(&(new_gai->src_addr),&(rtp_listinfo->src_addr));
781 COPY_ADDRESS(&(new_gai->dst_addr),&(rtp_listinfo->dest_addr));
782 new_gai->port_src = rtp_listinfo->src_port;
783 new_gai->port_dst = rtp_listinfo->dest_port;
784 duration = (guint32)(nstime_to_msec(&rtp_listinfo->stop_fd->rel_ts) - nstime_to_msec(&rtp_listinfo->start_fd->rel_ts));
785 new_gai->frame_label = g_strdup_printf("%s (%s) %s",
786 (rtp_listinfo->is_srtp)?"SRTP":"RTP",
787 rtp_listinfo->payload_type_str,
788 (rtp_listinfo->rtp_event == -1)?
789 "":val_to_str_ext_const(rtp_listinfo->rtp_event, &rtp_event_type_values_ext, "Unknown RTP Event"));
790 new_gai->comment = g_strdup_printf("%s Num packets:%u Duration:%u.%03us SSRC:0x%X",
791 (rtp_listinfo->is_srtp)?"SRTP":"RTP", rtp_listinfo->npackets,
792 duration/1000,(duration%1000), rtp_listinfo->ssrc);
793 new_gai->conv_num = conv_num;
794 set_fd_time(cfile.epan, new_gai->fd, time_str);
795 new_gai->time_str = g_strdup(time_str);
796 new_gai->display=FALSE;
797 new_gai->line_style = 2; /* the arrow line will be 2 pixels width */
798 tapinfo->graph_analysis->list = g_list_insert(tapinfo->graph_analysis->list, new_gai, item);
801 if (voip_calls_graph_list) item++;
805 voip_calls_graph_list = g_list_next(voip_calls_graph_list);
807 rtp_streams_list = g_list_next(rtp_streams_list);
812 /****************************************************************************/
814 rtp_init_tap(voip_calls_tapinfo_t *tap_id_base)
816 GString *error_string;
818 error_string = register_tap_listener("rtp", tap_base_to_id(tap_id_base, tap_id_offset_rtp_), NULL,
824 if (error_string != NULL) {
825 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
826 "%s", error_string->str);
827 g_string_free(error_string, TRUE);
831 /****************************************************************************/
833 remove_tap_listener_rtp(voip_calls_tapinfo_t *tap_id_base)
835 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_rtp_));
838 /****************************************************************************/
839 /******************************TAP for T38 **********************************/
840 /****************************************************************************/
842 /****************************************************************************/
843 /* whenever a T38 packet is seen by the tap listener */
845 t38_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *t38_info_ptr)
847 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_t38_);
849 voip_calls_info_t *callsinfo = NULL;
850 voip_calls_info_t *tmp_listinfo;
851 GList *voip_calls_graph_list = NULL;
853 gchar *frame_label = NULL;
854 gchar *comment = NULL;
855 seq_analysis_item_t *tmp_gai, *gai = NULL;
856 gchar *tmp_str1, *tmp_str2;
857 guint16 line_style = 2;
861 const t38_packet_info *t38_info = (const t38_packet_info *)t38_info_ptr;
863 if (t38_info->setup_frame_number != 0) {
864 /* using the setup frame number of the T38 packet, we get the call number that it belongs */
865 if(tapinfo->graph_analysis){
866 voip_calls_graph_list = g_queue_peek_nth_link(tapinfo->graph_analysis->items, 0);
868 while (voip_calls_graph_list)
870 tmp_gai = (seq_analysis_item_t *)voip_calls_graph_list->data;
871 if (t38_info->setup_frame_number == tmp_gai->fd->num) {
875 voip_calls_graph_list = g_list_next(voip_calls_graph_list);
877 if (gai) conv_num = (int) gai->conv_num;
880 /* 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
881 * have the associated Voip calls. It probably means the the packet was decoded using the default t38 port, or using "Decode as.."
882 * in this case we create a "voip" call that only have t38 media (no signaling)
883 * OR if we have not found the Setup message in the graph.
885 if ( (t38_info->setup_frame_number == 0) || (gai == NULL) ) {
886 /* check whether we already have a call with these parameters in the list */
887 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
890 tmp_listinfo=(voip_calls_info_t *)list->data;
891 if (tmp_listinfo->protocol == MEDIA_T38) {
892 callsinfo = (voip_calls_info_t*)(list->data);
895 list = g_list_next (list);
898 /* not in the list? then create a new entry */
899 if (callsinfo==NULL) {
900 callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
901 callsinfo->call_active_state = VOIP_ACTIVE;
902 callsinfo->call_state = VOIP_UNKNOWN;
903 callsinfo->from_identity=g_strdup("T38 Media only");
904 callsinfo->to_identity=g_strdup("T38 Media only");
905 COPY_ADDRESS(&(callsinfo->initial_speaker),&(pinfo->src));
906 callsinfo->selected=FALSE;
907 callsinfo->start_fd = pinfo->fd;
908 callsinfo->start_rel_ts = pinfo->rel_ts;
909 callsinfo->protocol=MEDIA_T38;
910 callsinfo->prot_info=NULL;
911 callsinfo->free_prot_info = NULL;
912 callsinfo->npackets = 0;
913 callsinfo->call_num = tapinfo->ncalls++;
914 g_queue_push_tail(tapinfo->callsinfos, callsinfo);
916 callsinfo->stop_fd = pinfo->fd;
917 callsinfo->stop_rel_ts = pinfo->rel_ts;
918 ++(callsinfo->npackets);
919 /* increment the packets counter of all calls */
920 ++(tapinfo->npackets);
922 conv_num = (int) callsinfo->call_num;
925 /* at this point we should have found the call num for this t38 packets belong */
926 if (conv_num == -1) {
930 /* add the item to the graph list */
931 if (t38_info->type_msg == 0) { /* 0=t30-indicator */
932 tmp_str1 = val_to_str_wmem(NULL, t38_info->t30ind_value, t38_T30_indicator_vals, "Ukn (0x%02X)");
933 frame_label = g_strdup(tmp_str1);
934 comment = g_strdup_printf("t38:t30 Ind:%s", tmp_str1);
935 wmem_free(NULL, tmp_str1);
937 } else if (t38_info->type_msg == 1) { /* 1=data */
938 switch(t38_info->Data_Field_field_type_value) {
939 case 0: /* hdlc-data */
941 case 2: /* hdlc-fcs-OK */
942 case 4: /* hdlc-fcs-OK-sig-end */
943 tmp_str1 = val_to_str_ext_wmem(NULL, t38_info->t30_Facsimile_Control & 0x7F,
944 &t30_facsimile_control_field_vals_short_ext,
946 frame_label = g_strdup_printf("%s %s",
949 wmem_free(NULL, tmp_str1);
951 tmp_str1 = val_to_str_ext_wmem(NULL, t38_info->t30_Facsimile_Control & 0x7F,
952 &t30_facsimile_control_field_vals_ext,
954 tmp_str2 = val_to_str_wmem(NULL, t38_info->data_value,
957 comment = g_strdup_printf("t38:%s:HDLC:%s", tmp_str2, tmp_str1);
958 wmem_free(NULL, tmp_str1);
959 wmem_free(NULL, tmp_str2);
961 case 3: /* hdlc-fcs-BAD */
962 case 5: /* hdlc-fcs-BAD-sig-end */
963 frame_label = g_strdup(t38_info->Data_Field_field_type_value == 3 ? "fcs-BAD" : "fcs-BAD-sig-end");
964 tmp_str1 = val_to_str_wmem(NULL, t38_info->data_value, t38_T30_data_vals, "Ukn (0x%02X)");
965 comment = g_strdup_printf("WARNING: received t38:%s:HDLC:%s",
967 t38_info->Data_Field_field_type_value == 3 ? "fcs-BAD" : "fcs-BAD-sig-end");
968 wmem_free(NULL, tmp_str1);
970 case 7: /* t4-non-ecm-sig-end */
971 duration = nstime_to_sec(&pinfo->rel_ts) - t38_info->time_first_t4_data;
972 tmp_str1 = val_to_str_wmem(NULL, t38_info->data_value, t38_T30_data_vals, "Ukn (0x%02X)");
973 frame_label = g_strdup_printf("t4-non-ecm-data:%s", tmp_str1);
974 comment = g_strdup_printf("t38:t4-non-ecm-data:%s Duration: %.2fs %s",
975 tmp_str1, duration, t38_info->desc_comment );
976 insert_to_graph_t38(tapinfo, pinfo, edt, frame_label, comment,
977 (guint16)conv_num, &(pinfo->src), &(pinfo->dst),
978 line_style, t38_info->frame_num_first_t4_data);
979 wmem_free(NULL, tmp_str1);
984 if (frame_label && !(t38_info->Data_Field_field_type_value == 7 && t38_info->type_msg == 1)) {
985 add_to_graph(tapinfo, pinfo, edt, frame_label, comment, (guint16)conv_num, &(pinfo->src), &(pinfo->dst), line_style);
991 tapinfo->redraw = TRUE;
993 return TRUE; /* refresh output */
996 /****************************************************************************/
998 t38_init_tap(voip_calls_tapinfo_t *tap_id_base)
1000 GString *error_string;
1002 error_string = register_tap_listener("t38", tap_base_to_id(tap_id_base, tap_id_offset_t38_), NULL,
1008 if (error_string != NULL) {
1009 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1010 "%s", error_string->str);
1011 g_string_free(error_string, TRUE);
1015 /****************************************************************************/
1017 remove_tap_listener_t38(voip_calls_tapinfo_t *tap_id_base)
1019 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_t38_));
1023 /****************************************************************************/
1024 /* ***************************TAP for SIP **********************************/
1025 /****************************************************************************/
1028 free_sip_info(gpointer p) {
1029 sip_calls_info_t *si = (sip_calls_info_t *)p;
1031 g_free(si->call_identifier);
1035 /****************************************************************************/
1036 /* whenever a SIP packet is seen by the tap listener */
1038 sip_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt , const void *SIPinfo)
1040 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sip_);
1041 /* we just take note of the ISUP data here; when we receive the MTP3 part everything will
1042 be compared with existing calls */
1044 voip_calls_info_t *callsinfo = NULL;
1045 sip_calls_info_t *tmp_sipinfo = NULL;
1046 address tmp_src, tmp_dst;
1047 gchar *frame_label = NULL;
1048 gchar *comment = NULL;
1049 gchar *old_comment = NULL;
1052 const sip_info_value_t *pi = (const sip_info_value_t *)SIPinfo;
1054 /* do not consider packets without call_id */
1055 if (pi->tap_call_id ==NULL) {
1058 key=pi->tap_call_id;
1059 /* init the hash table */
1060 if(NULL==tapinfo->callsinfo_hashtable[SIP_HASH]) {
1061 /* TODO: check how efficient g_str_hash is for sip call ids */
1062 tapinfo->callsinfo_hashtable[SIP_HASH]=g_hash_table_new_full(g_str_hash,
1064 NULL, /* key_destroy_func */
1065 NULL);/* value_destroy_func */
1067 /* search the call information in the SIP_HASH */
1068 callsinfo = (voip_calls_info_t *)g_hash_table_lookup(tapinfo->callsinfo_hashtable[SIP_HASH], key);
1070 /* Create a new flow entry if the message is INVITE in case of FLOW_ONLY_INVITES,
1071 Create a new flow entry for all messages which have a method in case of FLOW_ALL.
1072 Flows for REGISTER, OPTIONS, MESSAGE and other SIP methods can be seen. */
1074 if ((callsinfo==NULL) && (pi->request_method!=NULL)) {
1076 /* check VoIPcalls_get_flow_show_option() == FLOW_ALL or FLOW_ONLY_INVITES */
1078 if (tapinfo->fs_option == FLOW_ALL ||
1079 (tapinfo->fs_option == FLOW_ONLY_INVITES &&
1080 strcmp(pi->request_method,"INVITE")==0)) {
1081 callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
1082 callsinfo->call_active_state = VOIP_ACTIVE;
1083 callsinfo->call_state = VOIP_CALL_SETUP;
1084 callsinfo->from_identity=g_strdup(pi->tap_from_addr);
1085 callsinfo->to_identity=g_strdup(pi->tap_to_addr);
1086 COPY_ADDRESS(&(callsinfo->initial_speaker),&(pinfo->src));
1087 callsinfo->selected=FALSE;
1088 callsinfo->start_fd=pinfo->fd;
1089 callsinfo->start_rel_ts=pinfo->rel_ts;
1090 callsinfo->protocol=VOIP_SIP;
1091 callsinfo->prot_info=g_malloc(sizeof(sip_calls_info_t));
1092 callsinfo->free_prot_info = free_sip_info;
1093 callsinfo->call_id = g_strdup(pi->tap_call_id);
1094 tmp_sipinfo = (sip_calls_info_t *)callsinfo->prot_info;
1095 tmp_sipinfo->call_identifier = g_strdup(pi->tap_call_id);
1096 tmp_sipinfo->sip_state = SIP_INVITE_SENT;
1097 tmp_sipinfo->invite_cseq = pi->tap_cseq_number;
1098 callsinfo->npackets = 0;
1099 callsinfo->call_num = tapinfo->ncalls++;
1101 /* show method in comment in conversation list dialog, user can discern different conversation types */
1102 callsinfo->call_comment=g_strdup(pi->request_method);
1104 g_queue_push_tail(tapinfo->callsinfos, callsinfo);
1105 /* insert the call information in the SIP_HASH */
1106 g_hash_table_insert(tapinfo->callsinfo_hashtable[SIP_HASH],
1107 tmp_sipinfo->call_identifier, callsinfo);
1111 if (callsinfo != NULL) {
1112 tmp_sipinfo = (sip_calls_info_t *)callsinfo->prot_info;
1114 /* let's analyze the call state */
1116 COPY_ADDRESS(&(tmp_src), &(pinfo->src));
1117 COPY_ADDRESS(&(tmp_dst), &(pinfo->dst));
1119 if (pi->request_method == NULL) {
1120 frame_label = g_strdup_printf("%u %s", pi->response_code, pi->reason_phrase );
1121 comment = g_strdup_printf("SIP Status %u %s", pi->response_code, pi->reason_phrase );
1123 if ((tmp_sipinfo && pi->tap_cseq_number == tmp_sipinfo->invite_cseq)&&(ADDRESSES_EQUAL(&tmp_dst,&(callsinfo->initial_speaker)))) {
1124 if ((pi->response_code > 199) && (pi->response_code<300) && (tmp_sipinfo->sip_state == SIP_INVITE_SENT)) {
1125 tmp_sipinfo->sip_state = SIP_200_REC;
1127 else if ((pi->response_code>299)&&(tmp_sipinfo->sip_state == SIP_INVITE_SENT)) {
1128 callsinfo->call_state = VOIP_REJECTED;
1129 tapinfo->rejected_calls++;
1132 /* UPDATE comment in conversation list dialog with response code and reason.
1133 Multiple code(+reason) may be appended, so skip over intermediate codes (100 trying, 183 ringing, e.t.c.)
1134 TODO: is useful but not perfect, what is appended is truncated when displayed in dialog window */
1135 if (pi->response_code >= 200) {
1136 old_comment = callsinfo->call_comment;
1137 callsinfo->call_comment=g_strdup_printf("%s %u",
1138 callsinfo->call_comment,
1139 pi->response_code/*, pi->reason_phrase*/);
1141 g_free(old_comment);
1148 frame_label = g_strdup(pi->request_method);
1150 if ((strcmp(pi->request_method,"INVITE")==0)&&(ADDRESSES_EQUAL(&tmp_src,&(callsinfo->initial_speaker)))) {
1151 tmp_sipinfo->invite_cseq = pi->tap_cseq_number;
1152 callsinfo->call_state = VOIP_CALL_SETUP;
1153 /* TODO: sometimes truncated when displayed in dialog window */
1154 comment = g_strdup_printf("SIP INVITE From: %s To:%s Call-ID:%s CSeq:%d",
1155 callsinfo->from_identity, callsinfo->to_identity,
1156 callsinfo->call_id, pi->tap_cseq_number);
1158 else if ((strcmp(pi->request_method,"ACK")==0)&&(pi->tap_cseq_number == tmp_sipinfo->invite_cseq)
1159 &&(ADDRESSES_EQUAL(&tmp_src,&(callsinfo->initial_speaker)))&&(tmp_sipinfo->sip_state==SIP_200_REC)
1160 &&(callsinfo->call_state == VOIP_CALL_SETUP)) {
1161 callsinfo->call_state = VOIP_IN_CALL;
1162 comment = g_strdup_printf("SIP Request INVITE ACK 200 CSeq:%d", pi->tap_cseq_number);
1164 else if (strcmp(pi->request_method,"BYE")==0) {
1165 callsinfo->call_state = VOIP_COMPLETED;
1166 tapinfo->completed_calls++;
1167 comment = g_strdup_printf("SIP Request BYE CSeq:%d", pi->tap_cseq_number);
1169 else if ((strcmp(pi->request_method,"CANCEL")==0)&&(pi->tap_cseq_number == tmp_sipinfo->invite_cseq)
1170 &&(ADDRESSES_EQUAL(&tmp_src,&(callsinfo->initial_speaker)))&&(callsinfo->call_state==VOIP_CALL_SETUP)) {
1171 callsinfo->call_state = VOIP_CANCELLED;
1172 tmp_sipinfo->sip_state = SIP_CANCEL_SENT;
1173 comment = g_strdup_printf("SIP Request CANCEL CSeq:%d", pi->tap_cseq_number);
1175 /* comment = g_strdup_printf("SIP %s", pi->request_method); */
1176 tmp_sipinfo->invite_cseq = pi->tap_cseq_number;
1177 callsinfo->call_state = VOIP_CALL_SETUP;
1178 comment = g_strdup_printf("SIP %s From: %s To:%s CSeq:%d",
1180 callsinfo->from_identity,
1181 callsinfo->to_identity, pi->tap_cseq_number);
1185 callsinfo->stop_fd = pinfo->fd;
1186 callsinfo->stop_rel_ts = pinfo->rel_ts;
1187 ++(callsinfo->npackets);
1188 /* increment the packets counter of all calls */
1189 ++(tapinfo->npackets);
1191 /* add to the graph */
1192 add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
1194 g_free(frame_label);
1195 g_free((void *)tmp_src.data);
1196 g_free((void *)tmp_dst.data);
1198 /* add SDP info if apply */
1199 if ( (tapinfo->sdp_summary != NULL) && (tapinfo->sdp_frame_num == pinfo->fd->num) ) {
1200 append_to_frame_graph(tapinfo, pinfo->fd->num, tapinfo->sdp_summary, NULL);
1201 g_free(tapinfo->sdp_summary);
1202 tapinfo->sdp_summary = NULL;
1207 tapinfo->redraw = TRUE;
1209 return TRUE; /* refresh output */
1212 /****************************************************************************/
1214 /****************************************************************************/
1217 sip_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
1219 GString *error_string;
1221 error_string = register_tap_listener("sip", tap_base_to_id(tap_id_base, tap_id_offset_sip_), NULL,
1227 if (error_string != NULL) {
1228 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1229 "%s", error_string->str);
1230 g_string_free(error_string, TRUE);
1234 /****************************************************************************/
1236 remove_tap_listener_sip_calls(voip_calls_tapinfo_t *tap_id_base)
1238 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_sip_));
1241 /****************************************************************************/
1242 /* ***************************TAP for ISUP **********************************/
1243 /****************************************************************************/
1245 /****************************************************************************/
1246 /* whenever a isup_ packet is seen by the tap listener */
1248 isup_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *isup_info)
1250 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_isup_);
1251 voip_calls_info_t *tmp_listinfo;
1252 voip_calls_info_t *callsinfo = NULL;
1253 isup_calls_info_t *tmp_isupinfo;
1254 gboolean found = FALSE;
1255 gboolean forward = FALSE;
1256 gboolean right_pair;
1258 gchar *frame_label = NULL;
1259 gchar *comment = NULL;
1261 const isup_tap_rec_t *pi = (const isup_tap_rec_t *)isup_info;
1263 /* check if the lower layer is MTP matching the frame number */
1264 if (tapinfo->mtp3_frame_num != pinfo->fd->num)
1267 /* check whether we already have a call with these parameters in the list */
1268 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
1272 tmp_listinfo=(voip_calls_info_t *)list->data;
1273 if ((tmp_listinfo->protocol == VOIP_ISUP)&&(tmp_listinfo->call_active_state==VOIP_ACTIVE)) {
1274 tmp_isupinfo = (isup_calls_info_t *)tmp_listinfo->prot_info;
1275 if ((tmp_isupinfo->cic == pi->circuit_id)&&(tmp_isupinfo->ni == tapinfo->mtp3_ni)) {
1276 if ((tmp_isupinfo->opc == tapinfo->mtp3_opc)&&(tmp_isupinfo->dpc == tapinfo->mtp3_dpc)) {
1278 } else if ((tmp_isupinfo->dpc == tapinfo->mtp3_opc)&&(tmp_isupinfo->opc == tapinfo->mtp3_dpc)) {
1285 /* if there is an IAM for a call that is not in setup state, that means the previous call in the same
1286 cic is no longer active */
1287 if (tmp_listinfo->call_state == VOIP_CALL_SETUP) {
1289 } else if (pi->message_type != 1) {
1292 tmp_listinfo->call_active_state=VOIP_INACTIVE;
1297 callsinfo = (voip_calls_info_t*)(list->data);
1302 list = g_list_next (list);
1305 /* not in the list? then create a new entry if the message is IAM
1306 -i.e. if this session is a call*/
1308 if ((callsinfo==NULL) &&(pi->message_type==1)) {
1309 callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
1310 callsinfo->call_active_state = VOIP_ACTIVE;
1311 callsinfo->call_state = VOIP_UNKNOWN;
1312 COPY_ADDRESS(&(callsinfo->initial_speaker),&(pinfo->src));
1313 callsinfo->selected=FALSE;
1314 callsinfo->start_fd=pinfo->fd;
1315 callsinfo->start_rel_ts=pinfo->rel_ts;
1316 callsinfo->protocol=VOIP_ISUP;
1317 if (pi->calling_number!=NULL) {
1318 callsinfo->from_identity=g_strdup(pi->calling_number);
1320 if (pi->called_number!=NULL) {
1321 callsinfo->to_identity=g_strdup(pi->called_number);
1323 callsinfo->prot_info=g_malloc(sizeof(isup_calls_info_t));
1324 callsinfo->free_prot_info = g_free;
1325 tmp_isupinfo=(isup_calls_info_t *)callsinfo->prot_info;
1326 tmp_isupinfo->opc = tapinfo->mtp3_opc;
1327 tmp_isupinfo->dpc = tapinfo->mtp3_dpc;
1328 tmp_isupinfo->ni = tapinfo->mtp3_ni;
1329 tmp_isupinfo->cic = pi->circuit_id;
1330 callsinfo->npackets = 0;
1331 callsinfo->call_num = tapinfo->ncalls++;
1332 g_queue_push_tail(tapinfo->callsinfos, callsinfo);
1336 if (callsinfo!=NULL) {
1337 callsinfo->stop_fd = pinfo->fd;
1338 callsinfo->stop_rel_ts = pinfo->rel_ts;
1339 ++(callsinfo->npackets);
1341 /* Let's analyze the call state */
1343 frame_label = g_strdup(val_to_str_ext_const(pi->message_type, &isup_message_type_value_acro_ext, "Unknown"));
1345 if (callsinfo->npackets == 1) { /* this is the first packet, that must be an IAM */
1347 if ((pi->calling_number!=NULL)&&(pi->called_number !=NULL)) {
1348 comment = g_strdup_printf("Call from %s to %s",
1349 pi->calling_number, pi->called_number);
1351 } else if (callsinfo->npackets == 2) { /* in the second packet we show the SPs */
1353 comment = g_strdup_printf("%i-%i -> %i-%i. Cic:%i",
1354 tapinfo->mtp3_ni, tapinfo->mtp3_opc,
1355 tapinfo->mtp3_ni, tapinfo->mtp3_dpc, pi->circuit_id);
1357 comment = g_strdup_printf("%i-%i -> %i-%i. Cic:%i",
1358 tapinfo->mtp3_ni, tapinfo->mtp3_dpc,
1359 tapinfo->mtp3_ni, tapinfo->mtp3_opc, pi->circuit_id);
1363 switch(pi->message_type) {
1365 callsinfo->call_state=VOIP_CALL_SETUP;
1367 case 7: /* CONNECT */
1368 case 9: /* ANSWER */
1369 callsinfo->call_state=VOIP_IN_CALL;
1371 case 12: /* RELEASE */
1372 if (callsinfo->call_state==VOIP_CALL_SETUP) {
1374 callsinfo->call_state=VOIP_CANCELLED;
1377 callsinfo->call_state=VOIP_REJECTED;
1378 tapinfo->rejected_calls++;
1381 else if (callsinfo->call_state == VOIP_IN_CALL) {
1382 callsinfo->call_state = VOIP_COMPLETED;
1383 tapinfo->completed_calls++;
1385 comment = g_strdup_printf("Cause %i - %s",
1387 val_to_str_ext_const(pi->cause_value, &q931_cause_code_vals_ext, "(Unknown)"));
1391 /* increment the packets counter of all calls */
1392 ++(tapinfo->npackets);
1394 /* add to the graph */
1395 add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
1397 g_free(frame_label);
1400 tapinfo->redraw = TRUE;
1402 return TRUE; /* refresh output */
1405 /****************************************************************************/
1408 isup_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
1410 GString *error_string;
1412 error_string = register_tap_listener("isup", tap_base_to_id(tap_id_base, tap_id_offset_isup_),
1420 if (error_string != NULL) {
1421 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1422 "%s", error_string->str);
1423 g_string_free(error_string, TRUE);
1427 /****************************************************************************/
1430 remove_tap_listener_isup_calls(voip_calls_tapinfo_t *tap_id_base)
1432 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_isup_));
1435 /****************************************************************************/
1436 /* ***************************TAP for MTP3 **********************************/
1437 /****************************************************************************/
1440 /****************************************************************************/
1441 /* whenever a mtp3_ packet is seen by the tap listener */
1443 mtp3_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt _U_, const void *mtp3_info)
1445 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_mtp3_);
1446 const mtp3_tap_rec_t *pi = (const mtp3_tap_rec_t *)mtp3_info;
1448 /* keep the data in memory to use when the ISUP information arrives */
1450 tapinfo->mtp3_opc = pi->addr_opc.pc;
1451 tapinfo->mtp3_dpc = pi->addr_dpc.pc;
1452 tapinfo->mtp3_ni = pi->addr_opc.ni;
1453 tapinfo->mtp3_frame_num = pinfo->fd->num;
1458 /****************************************************************************/
1461 mtp3_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
1463 GString *error_string;
1465 error_string = register_tap_listener("mtp3", tap_base_to_id(tap_id_base, tap_id_offset_mtp3_),
1473 if (error_string != NULL) {
1474 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1475 "%s", error_string->str);
1476 g_string_free(error_string, TRUE);
1479 error_string = register_tap_listener("m3ua", tap_base_to_id(tap_id_base, tap_id_offset_m3ua_),
1487 if (error_string != NULL) {
1488 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1489 "%s", error_string->str);
1490 g_string_free(error_string, TRUE);
1495 /****************************************************************************/
1498 remove_tap_listener_mtp3_calls(voip_calls_tapinfo_t *tap_id_base)
1500 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_mtp3_));
1501 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_m3ua_));
1504 /****************************************************************************/
1505 /* ***************************TAP for Q931 **********************************/
1506 /****************************************************************************/
1507 static void h245_add_to_graph(voip_calls_tapinfo_t *tapinfo, guint32 new_frame_num);
1508 static const e_guid_t guid_allzero = {0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } };
1509 /* defines specific H323 data */
1511 /****************************************************************************/
1512 /* whenever a q931_ packet is seen by the tap listener */
1514 q931_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *q931_info)
1517 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_q931_);
1518 h323_calls_info_t *tmp_h323info,*tmp2_h323info;
1519 actrace_isdn_calls_info_t *tmp_actrace_isdn_info;
1520 voip_calls_info_t *tmp_listinfo;
1521 voip_calls_info_t *callsinfo = NULL;
1522 h245_address_t *h245_add = NULL;
1523 gchar *comment, *tmp_str;
1525 const q931_packet_info *pi = (const q931_packet_info *)q931_info;
1527 /* free previously allocated q931_calling/ed_number */
1528 g_free(tapinfo->q931_calling_number);
1529 g_free(tapinfo->q931_called_number);
1531 if (pi->calling_number!=NULL)
1532 tapinfo->q931_calling_number = g_strdup(pi->calling_number);
1534 tapinfo->q931_calling_number = g_strdup("");
1536 if (pi->called_number!=NULL)
1537 tapinfo->q931_called_number = g_strdup(pi->called_number);
1539 tapinfo->q931_called_number = g_strdup("");
1540 tapinfo->q931_cause_value = pi->cause_value;
1541 tapinfo->q931_frame_num = pinfo->fd->num;
1542 tapinfo->q931_crv = pi->crv;
1545 /* add staff to H323 calls */
1546 if (tapinfo->h225_frame_num == tapinfo->q931_frame_num) {
1547 tmp_h323info = NULL;
1548 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
1551 tmp_listinfo=(voip_calls_info_t *)list->data;
1552 if ( (tmp_listinfo->protocol == VOIP_H323) && (tmp_listinfo->call_num == tapinfo->h225_call_num) ) {
1553 tmp_h323info = (h323_calls_info_t *)tmp_listinfo->prot_info;
1554 callsinfo = (voip_calls_info_t*)(list->data);
1556 /* Add the CRV to the h323 call */
1557 if (tmp_h323info->q931_crv == -1) {
1558 tmp_h323info->q931_crv = tapinfo->q931_crv;
1559 } else if (tmp_h323info->q931_crv != tapinfo->q931_crv) {
1560 tmp_h323info->q931_crv2 = tapinfo->q931_crv;
1564 list = g_list_next (list);
1567 if (callsinfo != NULL) {
1569 if (tapinfo->h225_cstype == H225_SETUP) {
1570 /* set te calling and called number from the Q931 packet */
1571 if (tapinfo->q931_calling_number != NULL) {
1572 g_free(callsinfo->from_identity);
1573 callsinfo->from_identity=g_strdup(tapinfo->q931_calling_number);
1575 if (tapinfo->q931_called_number != NULL) {
1576 g_free(callsinfo->to_identity);
1577 callsinfo->to_identity=g_strdup(tapinfo->q931_called_number);
1580 /* check if there is an LRQ/LCF that match this Setup */
1581 /* TODO: we are just checking the DialedNumer in LRQ/LCF against the Setup
1582 we should also check if the h225 signaling IP and port match the destination
1583 Setup ip and port */
1584 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
1587 tmp_listinfo=(voip_calls_info_t *)list->data;
1588 if (tmp_listinfo->protocol == VOIP_H323) {
1589 tmp2_h323info = (h323_calls_info_t *)tmp_listinfo->prot_info;
1591 /* check if the called number match a LRQ/LCF */
1592 if ( (strcmp(callsinfo->to_identity, tmp_listinfo->to_identity)==0)
1593 && (memcmp(&tmp2_h323info->guid, &guid_allzero, GUID_LEN) == 0) ) {
1594 /* change the call graph to the LRQ/LCF to belong to this call */
1595 callsinfo->npackets += change_call_num_graph(tapinfo, tmp_listinfo->call_num, callsinfo->call_num);
1597 /* remove this LRQ/LCF call entry because we have found the Setup that match them */
1598 g_free(tmp_listinfo->from_identity);
1599 g_free(tmp_listinfo->to_identity);
1600 DUMP_PTR2(tmp2_h323info->guid);
1601 g_free(tmp2_h323info->guid);
1603 list2 = g_list_first(tmp2_h323info->h245_list);
1606 h245_add=(h245_address_t *)list2->data;
1607 g_free((void *)h245_add->h245_address.data);
1608 g_free(list2->data);
1609 list2 = g_list_next(list2);
1611 g_list_free(tmp_h323info->h245_list);
1612 tmp_h323info->h245_list = NULL;
1613 g_free(tmp_listinfo->prot_info);
1614 g_queue_unlink(tapinfo->callsinfos, list);
1618 list = g_list_next (list);
1621 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"),
1622 (tapinfo->h225_is_faststart==TRUE?"on":"off"));
1623 } else if (tapinfo->h225_cstype == H225_RELEASE_COMPLET) {
1624 /* get the Q931 Release cause code */
1625 if (tapinfo->q931_cause_value != 0xFF) {
1626 comment = g_strdup_printf("H225 Q931 Rel Cause (%i):%s", tapinfo->q931_cause_value,
1627 val_to_str_ext_const(tapinfo->q931_cause_value, &q931_cause_code_vals_ext, "<unknown>"));
1628 } else { /* Cause not set */
1629 comment = g_strdup("H225 No Q931 Rel Cause");
1632 /* change the graph comment for this new one */
1633 if (comment != NULL) {
1634 change_frame_graph(tapinfo, tapinfo->h225_frame_num, NULL, comment);
1638 /* we reset the h225_frame_num to 0 because there could be empty h225 in the same frame
1639 as non empty h225 (e.g connect), so we don't have to be here twice */
1640 tapinfo->h225_frame_num = 0;
1642 /* add staff to H245 */
1643 } else if (tapinfo->h245_labels->frame_num == tapinfo->q931_frame_num) {
1644 /* there are empty H225 frames that don't have guid (guaid=0) but they have h245 info,
1645 so the only way to match those frames is with the Q931 CRV number */
1646 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
1649 tmp_listinfo=(voip_calls_info_t *)list->data;
1650 if (tmp_listinfo->protocol == VOIP_H323) {
1651 tmp_h323info = (h323_calls_info_t *)tmp_listinfo->prot_info;
1652 if ( ((tmp_h323info->q931_crv == tapinfo->q931_crv) || (tmp_h323info->q931_crv2 == tapinfo->q931_crv)) && (tapinfo->q931_crv!=-1)) {
1653 /* if the frame number exists in graph, append to it*/
1654 if (!append_to_frame_graph(tapinfo, tapinfo->q931_frame_num, NULL, NULL)) {
1655 /* if not exist, add to the graph */
1656 add_to_graph(tapinfo, pinfo, edt, NULL, NULL, tmp_listinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
1657 ++(tmp_listinfo->npackets);
1658 /* increment the packets counter of all calls */
1659 ++(tapinfo->npackets);
1662 /* Add the H245 info if exists to the Graph */
1663 h245_add_to_graph(tapinfo, pinfo->fd->num);
1667 list = g_list_next (list);
1670 /* add stuff to ACTRACE */
1676 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
1679 tmp_listinfo=(voip_calls_info_t *)list->data;
1680 if ( tmp_listinfo->protocol == VOIP_AC_ISDN ) {
1681 tmp_actrace_isdn_info = (actrace_isdn_calls_info_t *)tmp_listinfo->prot_info;
1682 /* TODO: Also check the IP of the Blade, and if the call is complete (no active) */
1683 if ( (tmp_actrace_isdn_info->crv == tapinfo->q931_crv) && (tmp_actrace_isdn_info->trunk == tapinfo->actrace_trunk) ) {
1684 callsinfo = (voip_calls_info_t*)(list->data);
1688 list = g_list_next (list);
1691 SET_ADDRESS(&pstn_add, AT_STRINGZ, 5, g_strdup("PSTN"));
1693 /* if it is a new call, add it to the list */
1695 callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
1696 callsinfo->call_active_state = VOIP_ACTIVE;
1697 callsinfo->call_state = VOIP_CALL_SETUP;
1698 callsinfo->from_identity=g_strdup(tapinfo->q931_calling_number);
1699 callsinfo->to_identity=g_strdup(tapinfo->q931_called_number);
1700 COPY_ADDRESS(&(callsinfo->initial_speaker),tapinfo->actrace_direction?&pstn_add:&(pinfo->src));
1701 callsinfo->selected=FALSE;
1702 callsinfo->start_fd=pinfo->fd;
1703 callsinfo->start_rel_ts=pinfo->rel_ts;
1704 callsinfo->protocol=VOIP_AC_ISDN;
1705 callsinfo->prot_info=g_malloc(sizeof(actrace_isdn_calls_info_t));
1706 callsinfo->free_prot_info = g_free;
1707 tmp_actrace_isdn_info=(actrace_isdn_calls_info_t *)callsinfo->prot_info;
1708 tmp_actrace_isdn_info->crv=tapinfo->q931_crv;
1709 tmp_actrace_isdn_info->trunk=tapinfo->actrace_trunk;
1710 callsinfo->npackets = 0;
1711 callsinfo->call_num = tapinfo->ncalls++;
1712 g_queue_push_tail(tapinfo->callsinfos, callsinfo);
1715 callsinfo->stop_fd = pinfo->fd;
1716 callsinfo->stop_rel_ts = pinfo->rel_ts;
1717 ++(callsinfo->npackets);
1718 /* increment the packets counter of all calls */
1719 ++(tapinfo->npackets);
1721 switch(pi->message_type) {
1723 comment = g_strdup_printf("AC_ISDN trunk:%u Calling: %s Called:%s", tapinfo->actrace_trunk, tapinfo->q931_calling_number, tapinfo->q931_called_number);
1724 callsinfo->call_state=VOIP_CALL_SETUP;
1727 callsinfo->call_state=VOIP_IN_CALL;
1729 case Q931_RELEASE_COMPLETE:
1731 case Q931_DISCONNECT:
1732 if (callsinfo->call_state==VOIP_CALL_SETUP) {
1733 if (ADDRESSES_EQUAL(&(callsinfo->initial_speaker), tapinfo->actrace_direction?&pstn_add:&(pinfo->src) )) { /* forward direction */
1734 callsinfo->call_state=VOIP_CANCELLED;
1736 else { /* reverse */
1737 callsinfo->call_state=VOIP_REJECTED;
1738 tapinfo->rejected_calls++;
1740 } else if ( (callsinfo->call_state!=VOIP_CANCELLED) && (callsinfo->call_state!=VOIP_REJECTED) ) {
1741 callsinfo->call_state=VOIP_COMPLETED;
1742 tapinfo->completed_calls++;
1744 if (tapinfo->q931_cause_value != 0xFF) {
1745 comment = g_strdup_printf("AC_ISDN trunk:%u Q931 Rel Cause (%i):%s", tapinfo->actrace_trunk, tapinfo->q931_cause_value,
1746 val_to_str_ext_const(tapinfo->q931_cause_value, &q931_cause_code_vals_ext, "<unknown>"));
1747 } else { /* Cause not set */
1748 comment = g_strdup("AC_ISDN No Q931 Rel Cause");
1754 comment = g_strdup_printf("AC_ISDN trunk:%u", tapinfo->actrace_trunk );
1756 tmp_str = val_to_str_wmem(NULL, pi->message_type, q931_message_type_vals, "<unknown (%d)>");
1757 add_to_graph(tapinfo, pinfo, edt, tmp_str, comment, callsinfo->call_num,
1758 tapinfo->actrace_direction?&pstn_add:&(pinfo->src),
1759 tapinfo->actrace_direction?&(pinfo->src):&pstn_add,
1761 wmem_free(NULL, tmp_str);
1764 g_free((char *)pstn_add.data);
1767 tapinfo->redraw = TRUE;
1769 return TRUE; /* refresh output */
1772 /****************************************************************************/
1775 q931_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
1777 GString *error_string;
1779 error_string = register_tap_listener("q931", tap_base_to_id(tap_id_base, tap_id_offset_q931_),
1787 if (error_string != NULL) {
1788 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1789 "%s", error_string->str);
1790 g_string_free(error_string, TRUE);
1794 /****************************************************************************/
1797 remove_tap_listener_q931_calls(voip_calls_tapinfo_t *tap_id_base)
1799 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_q931_));
1802 /****************************************************************************/
1803 /****************************TAP for H323 ***********************************/
1804 /****************************************************************************/
1807 add_h245_Address(h323_calls_info_t *h323info, h245_address_t *h245_address)
1809 h323info->h245_list = g_list_prepend(h323info->h245_list, h245_address);
1814 free_h225_info(gpointer p) {
1815 h323_calls_info_t *tmp_h323info = (h323_calls_info_t *)p;
1817 DUMP_PTR2(tmp_h323info->guid);
1818 g_free(tmp_h323info->guid);
1820 if (tmp_h323info->h245_list) {
1821 GList *list2 = g_list_first(tmp_h323info->h245_list);
1824 h245_address_t *h245_add=(h245_address_t *)list2->data;
1825 g_free((void *)h245_add->h245_address.data);
1826 g_free(list2->data);
1827 list2 = g_list_next(list2);
1830 g_list_free(tmp_h323info->h245_list);
1836 /****************************************************************************/
1837 /* whenever a H225 packet is seen by the tap listener */
1839 h225_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *H225info)
1841 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_h225_);
1842 voip_calls_info_t *tmp_listinfo;
1843 voip_calls_info_t *callsinfo = NULL;
1844 h323_calls_info_t *tmp_h323info = NULL;
1848 h245_address_t *h245_add = NULL;
1850 const h225_packet_info *pi = (const h225_packet_info *)H225info;
1852 /* if not guid and RAS and not LRQ, LCF or LRJ return because did not belong to a call */
1853 /* OR, if not guid and is H225 return because doesn't belong to a call */
1854 if ((memcmp(&pi->guid, &guid_allzero, GUID_LEN) == 0))
1855 if ( ((pi->msg_type == H225_RAS) && ((pi->msg_tag < 18) || (pi->msg_tag > 20))) || (pi->msg_type != H225_RAS) )
1858 /* if it is RAS LCF or LRJ*/
1859 if ( (pi->msg_type == H225_RAS) && ((pi->msg_tag == 19) || (pi->msg_tag == 20))) {
1860 /* if the LCF/LRJ doesn't match to a LRQ, just return */
1861 if (!pi->request_available) return FALSE;
1863 /* check whether we already have a call with this request SeqNum */
1864 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
1867 tmp_listinfo=(voip_calls_info_t *)list->data;
1868 g_assert(tmp_listinfo != NULL);
1869 if (tmp_listinfo->protocol == VOIP_H323) {
1870 tmp_h323info = (h323_calls_info_t *)tmp_listinfo->prot_info;
1871 if (tmp_h323info->requestSeqNum == pi->requestSeqNum) {
1872 callsinfo = (voip_calls_info_t*)(list->data);
1876 list = g_list_next (list);
1879 /* check whether we already have a call with this guid in the list */
1880 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
1883 tmp_listinfo=(voip_calls_info_t *)list->data;
1884 if (tmp_listinfo->protocol == VOIP_H323) {
1885 tmp_h323info = (h323_calls_info_t *)tmp_listinfo->prot_info;
1886 g_assert(tmp_h323info != NULL);
1887 if ( (memcmp(tmp_h323info->guid, &guid_allzero, GUID_LEN) != 0) && (memcmp(tmp_h323info->guid, &pi->guid,GUID_LEN)==0) ) {
1888 callsinfo = (voip_calls_info_t*)(list->data);
1892 list = g_list_next (list);
1896 tapinfo->h225_cstype = pi->cs_type;
1897 tapinfo->h225_is_faststart = pi->is_faststart;
1899 /* not in the list? then create a new entry */
1900 if (callsinfo==NULL) {
1901 callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
1902 callsinfo->call_active_state = VOIP_ACTIVE;
1903 callsinfo->call_state = VOIP_UNKNOWN;
1904 callsinfo->from_identity=g_strdup("");
1905 callsinfo->to_identity=g_strdup("");
1906 COPY_ADDRESS(&(callsinfo->initial_speaker),&(pinfo->src));
1907 callsinfo->selected=FALSE;
1908 callsinfo->start_fd=pinfo->fd;
1909 callsinfo->start_rel_ts=pinfo->rel_ts;
1910 callsinfo->protocol=VOIP_H323;
1911 callsinfo->prot_info=g_malloc(sizeof(h323_calls_info_t));
1912 callsinfo->free_prot_info = free_h225_info;
1914 tmp_h323info = (h323_calls_info_t *)callsinfo->prot_info;
1915 g_assert(tmp_h323info != NULL);
1916 tmp_h323info->guid = (e_guid_t *)g_memdup(&pi->guid, sizeof pi->guid);
1917 DUMP_PTR1(tmp_h323info->guid);
1919 tmp_h323info->h225SetupAddr.type = AT_NONE;
1920 tmp_h323info->h225SetupAddr.len = 0;
1921 tmp_h323info->h245_list = NULL;
1922 tmp_h323info->is_faststart_Setup = FALSE;
1923 tmp_h323info->is_faststart_Proc = FALSE;
1924 tmp_h323info->is_h245Tunneling = FALSE;
1925 tmp_h323info->is_h245 = FALSE;
1926 tmp_h323info->q931_crv = -1;
1927 tmp_h323info->q931_crv2 = -1;
1928 tmp_h323info->requestSeqNum = 0;
1929 callsinfo->call_num = tapinfo->ncalls++;
1930 callsinfo->npackets = 0;
1932 g_queue_push_tail(tapinfo->callsinfos, callsinfo);
1935 tapinfo->h225_frame_num = pinfo->fd->num;
1936 tapinfo->h225_call_num = callsinfo->call_num;
1938 /* let's analyze the call state */
1940 callsinfo->stop_fd = pinfo->fd;
1941 callsinfo->stop_rel_ts = pinfo->rel_ts;
1942 ++(callsinfo->npackets);
1943 /* increment the packets counter of all calls */
1944 ++(tapinfo->npackets);
1947 /* XXX: it is supposed to be initialized isn't it? */
1948 g_assert(tmp_h323info != NULL);
1950 /* change the status */
1951 if (pi->msg_type == H225_CS) {
1953 /* this is still IPv4 only, because the dissector is */
1954 if (pi->is_h245 == TRUE) {
1955 h245_add = (h245_address_t *)g_malloc(sizeof (h245_address_t));
1956 h245_add->h245_address.type=AT_IPv4;
1957 h245_add->h245_address.len=4;
1958 h245_add->h245_address.data = g_malloc(sizeof(pi->h245_address));
1959 memcpy((void *)(h245_add->h245_address.data), &(pi->h245_address), 4);
1960 h245_add->h245_port = pi->h245_port;
1961 add_h245_Address(tmp_h323info, h245_add);
1964 if (pi->cs_type != H225_RELEASE_COMPLET) tmp_h323info->is_h245Tunneling = pi->is_h245Tunneling;
1966 frame_label = g_strdup(pi->frame_label);
1968 switch(pi->cs_type) {
1970 tmp_h323info->is_faststart_Setup = pi->is_faststart;
1972 /* Set the Setup address if it was not set */
1973 if (tmp_h323info->h225SetupAddr.type == AT_NONE)
1974 COPY_ADDRESS(&(tmp_h323info->h225SetupAddr), &(pinfo->src));
1975 callsinfo->call_state=VOIP_CALL_SETUP;
1976 comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
1977 (pi->is_faststart==TRUE?"on":"off"));
1980 callsinfo->call_state=VOIP_IN_CALL;
1981 if (pi->is_faststart == TRUE) tmp_h323info->is_faststart_Proc = TRUE;
1982 comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
1983 (pi->is_faststart==TRUE?"on":"off"));
1985 case H225_RELEASE_COMPLET:
1986 if (callsinfo->call_state==VOIP_CALL_SETUP) {
1987 if (ADDRESSES_EQUAL(&(tmp_h323info->h225SetupAddr),&(pinfo->src))) { /* forward direction */
1988 callsinfo->call_state=VOIP_CANCELLED;
1990 else { /* reverse */
1991 callsinfo->call_state=VOIP_REJECTED;
1992 tapinfo->rejected_calls++;
1995 callsinfo->call_state=VOIP_COMPLETED;
1996 tapinfo->completed_calls++;
1998 comment = g_strdup("H225 No Q931 Rel Cause");
2002 case H225_CALL_PROCEDING:
2003 if (pi->is_faststart == TRUE) tmp_h323info->is_faststart_Proc = TRUE;
2004 comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
2005 (pi->is_faststart==TRUE?"on":"off"));
2008 comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
2009 (pi->is_faststart==TRUE?"on":"off"));
2013 else if (pi->msg_type == H225_RAS) {
2014 switch(pi->msg_tag) {
2016 if (!pi->is_duplicate) {
2017 g_free(callsinfo->to_identity);
2018 callsinfo->to_identity=g_strdup(pi->dialedDigits);
2019 tmp_h323info->requestSeqNum = pi->requestSeqNum;
2023 if (strlen(pi->dialedDigits))
2024 comment = g_strdup_printf("H225 RAS dialedDigits: %s", pi->dialedDigits);
2026 comment = g_strdup("H225 RAS");
2029 comment = g_strdup("H225 RAS");
2031 frame_label = g_strdup(val_to_str_const(pi->msg_tag, h225_RasMessage_vals, "<unknown>"));
2033 frame_label = g_strdup("H225: Unknown");
2037 /* add to graph analysis */
2039 /* if the frame number exists in graph, append to it*/
2040 if (!append_to_frame_graph(tapinfo, pinfo->fd->num, pi->frame_label, comment)) {
2041 /* if not exist, add to the graph */
2042 add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
2045 /* Add the H245 info if exists to the Graph */
2046 h245_add_to_graph(tapinfo, pinfo->fd->num);
2048 g_free(frame_label);
2051 tapinfo->redraw = TRUE;
2053 return TRUE; /* refresh output */
2057 /****************************************************************************/
2059 /****************************************************************************/
2061 h225_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
2063 GString *error_string;
2065 error_string = register_tap_listener("h225", tap_base_to_id(tap_id_base, tap_id_offset_h225_), NULL,
2072 if (error_string != NULL) {
2073 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2074 "%s", error_string->str);
2075 g_string_free(error_string, TRUE);
2079 /****************************************************************************/
2081 remove_tap_listener_h225_calls(voip_calls_tapinfo_t *tap_id_base)
2083 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_h225_));
2086 /* Add the h245 label info to the graph */
2088 h245_add_to_graph(voip_calls_tapinfo_t *tapinfo, guint32 new_frame_num)
2092 if (new_frame_num != tapinfo->h245_labels->frame_num) return;
2094 for (n=0; n<tapinfo->h245_labels->labels_count; n++) {
2095 append_to_frame_graph(tapinfo, new_frame_num, tapinfo->h245_labels->labels[n].frame_label, tapinfo->h245_labels->labels[n].comment);
2096 g_free(tapinfo->h245_labels->labels[n].frame_label);
2097 tapinfo->h245_labels->labels[n].frame_label = NULL;
2098 g_free(tapinfo->h245_labels->labels[n].comment);
2099 tapinfo->h245_labels->labels[n].comment = NULL;
2101 tapinfo->h245_labels->frame_num = 0;
2102 tapinfo->h245_labels->labels_count = 0;
2105 /* free the h245_labels if the frame number is different */
2107 h245_free_labels(voip_calls_tapinfo_t *tapinfo, guint32 new_frame_num)
2111 if (new_frame_num == tapinfo->h245_labels->frame_num) return;
2113 for (n=0; n<tapinfo->h245_labels->labels_count; n++) {
2114 g_free(tapinfo->h245_labels->labels[n].frame_label);
2115 tapinfo->h245_labels->labels[n].frame_label = NULL;
2116 g_free(tapinfo->h245_labels->labels[n].comment);
2117 tapinfo->h245_labels->labels[n].comment = NULL;
2119 tapinfo->h245_labels->frame_num = 0;
2120 tapinfo->h245_labels->labels_count = 0;
2123 /* add the frame_label and comment to h245_labels and free the actual one if it is different frame num */
2125 h245_add_label(voip_calls_tapinfo_t *tapinfo, guint32 new_frame_num, const gchar *frame_label, const gchar *comment)
2127 h245_free_labels(tapinfo, new_frame_num);
2129 tapinfo->h245_labels->frame_num = new_frame_num;
2130 tapinfo->h245_labels->labels[tapinfo->h245_labels->labels_count].frame_label = g_strdup(frame_label);
2131 tapinfo->h245_labels->labels[tapinfo->h245_labels->labels_count].comment = g_strdup(comment);
2133 if (tapinfo->h245_labels->labels_count < (H245_MAX-1))
2134 tapinfo->h245_labels->labels_count++;
2138 /****************************************************************************/
2139 /* whenever a H245dg packet is seen by the tap listener (when H245 tunneling is ON) */
2141 h245dg_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *H245info)
2143 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_h245dg_);
2144 voip_calls_info_t *tmp_listinfo;
2145 voip_calls_info_t *callsinfo = NULL;
2146 h323_calls_info_t *tmp_h323info;
2149 h245_address_t *h245_add = NULL;
2151 const h245_packet_info *pi = (const h245_packet_info *)H245info;
2153 /* check if Tunneling is OFF and we have a call with this H245 add */
2154 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
2157 tmp_listinfo=(voip_calls_info_t *)list->data;
2158 if (tmp_listinfo->protocol == VOIP_H323) {
2159 tmp_h323info = (h323_calls_info_t *)tmp_listinfo->prot_info;
2161 list2 = g_list_first(tmp_h323info->h245_list);
2164 h245_add=(h245_address_t *)list2->data;
2165 if ( (ADDRESSES_EQUAL(&(h245_add->h245_address),&(pinfo->src)) && (h245_add->h245_port == pinfo->srcport))
2166 || (ADDRESSES_EQUAL(&(h245_add->h245_address),&(pinfo->dst)) && (h245_add->h245_port == pinfo->destport)) ) {
2167 callsinfo = (voip_calls_info_t*)(list->data);
2169 ++(callsinfo->npackets);
2170 /* increment the packets counter of all calls */
2171 ++(tapinfo->npackets);
2175 list2 = g_list_next(list2);
2177 if (callsinfo!=NULL) break;
2179 list = g_list_next(list);
2182 /* Tunnel is OFF, and we matched the h245 add so we add it to graph */
2183 if (callsinfo!=NULL) {
2184 ++(callsinfo->npackets);
2185 /* increment the packets counter of all calls */
2186 ++(tapinfo->npackets);
2187 /* if the frame number exists in graph, append to it*/
2188 if (!append_to_frame_graph(tapinfo, pinfo->fd->num, pi->frame_label, pi->comment)) {
2189 /* if not exist, add to the graph */
2190 add_to_graph(tapinfo, pinfo, edt, pi->frame_label, pi->comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
2193 /* Tunnel is ON, so we save the label info to use it into h225 or q931 tap. OR may be
2194 tunnel OFF but we did not matched the h245 add, in this case nobady will set this label
2195 since the frame_num will not match */
2197 h245_add_label(tapinfo, pinfo->fd->num, (gchar *) pi->frame_label, (gchar *) pi->comment);
2200 tapinfo->redraw = TRUE;
2202 return TRUE; /* refresh output */
2206 /****************************************************************************/
2208 /****************************************************************************/
2210 h245dg_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
2212 GString *error_string;
2214 error_string = register_tap_listener("h245dg", tap_base_to_id(tap_id_base, tap_id_offset_h245dg_), NULL,
2217 h245dg_calls_packet,
2221 if (error_string != NULL) {
2222 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2223 "%s", error_string->str);
2224 g_string_free(error_string, TRUE);
2228 /****************************************************************************/
2230 remove_tap_listener_h245dg_calls(voip_calls_tapinfo_t *tap_id_base)
2232 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_h245dg_));
2235 /****************************************************************************/
2236 /****************************TAP for SDP PROTOCOL ***************************/
2237 /****************************************************************************/
2238 /* whenever a SDP packet is seen by the tap listener */
2240 sdp_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt _U_, const void *SDPinfo)
2242 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sdp_);
2243 const sdp_packet_info *pi = (const sdp_packet_info *)SDPinfo;
2245 /* There are protocols like MGCP/SIP where the SDP is called before the tap for the
2246 MGCP/SIP packet, in those cases we assign the SPD summary to global lastSDPsummary
2249 g_free(tapinfo->sdp_summary);
2250 tapinfo->sdp_frame_num = pinfo->fd->num;
2251 /* Append to graph the SDP summary if the packet exists */
2252 tapinfo->sdp_summary = g_strdup_printf("SDP (%s)", pi->summary_str);
2253 append_to_frame_graph(tapinfo, pinfo->fd->num, tapinfo->sdp_summary, NULL);
2255 tapinfo->redraw = TRUE;
2257 return TRUE; /* refresh output */
2261 /****************************************************************************/
2263 /****************************************************************************/
2265 sdp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
2267 GString *error_string;
2269 error_string = register_tap_listener("sdp", tap_base_to_id(tap_id_base, tap_id_offset_sdp_), NULL,
2276 if (error_string != NULL) {
2277 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2278 "%s", error_string->str);
2279 g_string_free(error_string, TRUE);
2283 /****************************************************************************/
2285 remove_tap_listener_sdp_calls(voip_calls_tapinfo_t *tap_id_base)
2287 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_sdp_));
2290 /****************************************************************************/
2291 /* ***************************TAP for MGCP **********************************/
2292 /****************************************************************************/
2295 This function will look for a signal/event in the SignalReq/ObsEvent string
2296 and return true if it is found
2299 is_mgcp_signal(const gchar *signal_str_p, const gchar *signalStr)
2302 gchar **resultArray;
2304 /* if there is no signalStr, just return false */
2305 if (signalStr == NULL) return FALSE;
2307 /* if are both "blank" return true */
2308 if ( (*signal_str_p == '\0') && (*signalStr == '\0') ) return TRUE;
2310 /* look for signal in signalStr */
2311 resultArray = g_strsplit(signalStr, ",", 10);
2313 for (i = 0; resultArray[i]; i++) {
2314 g_strstrip(resultArray[i]);
2315 if (strcmp(resultArray[i], signal_str_p) == 0) return TRUE;
2318 g_strfreev(resultArray);
2324 This function will get the Caller ID info and replace the current string
2325 This is how it looks the caller Id: rg, ci(02/16/08/29, "3035550002","Ale Sipura 2")
2328 mgcp_caller_id(gchar *signalStr, gchar **callerId)
2332 /* if there is no signalStr, just return false */
2333 if (signalStr == NULL) return;
2335 arrayStr = g_strsplit(signalStr, "\"", 3);
2337 /* look for the ci signal */
2338 if (g_strv_length(arrayStr) == 3 && strstr(arrayStr[0], "ci(")) {
2339 /* free the previous "From" field of the call, and assign the new */
2341 *callerId = g_strdup(arrayStr[1]);
2343 g_strfreev(arrayStr);
2347 This function will get the Dialed Digits and replace the current string
2348 This is how it looks the dialed digits 5,5,5,0,0,0,2,#,*
2351 mgcp_dialed_digits(gchar *signalStr, gchar **dialedDigits)
2357 /* start with 1 for the null-terminator */
2358 guint resultStrLen = 1;
2360 /* if there is no signalStr, just return false */
2361 if (signalStr == NULL) return;
2363 tmpStr = g_strdup(signalStr);
2365 for ( i = 0 ; tmpStr[i] ; i++) {
2366 switch (tmpStr[i]) {
2367 case '0' : case '1' : case '2' : case '3' : case '4' :
2368 case '5' : case '6' : case '7' : case '8' : case '9' :
2369 case '#' : case '*' :
2378 if (resultStrLen == 1) {
2383 resultStr = (gchar *)g_malloc(resultStrLen);
2385 for (i = 0, j = 0; tmpStr[i]; i++) {
2386 if (tmpStr[i] != '?')
2387 resultStr[j++] = tmpStr[i];
2389 resultStr[j] = '\0';
2391 g_free(*dialedDigits);
2394 *dialedDigits = resultStr;
2401 /****************************************************************************/
2402 /* whenever a MGCP packet is seen by the tap listener */
2404 mgcp_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *MGCPinfo)
2406 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_mgcp_);
2407 voip_calls_info_t *tmp_listinfo;
2408 voip_calls_info_t *callsinfo = NULL;
2409 mgcp_calls_info_t *tmp_mgcpinfo = NULL;
2411 GList *listGraph = NULL;
2412 gchar *frame_label = NULL;
2413 gchar *comment = NULL;
2414 seq_analysis_item_t *gai = NULL;
2415 gboolean newcall = FALSE;
2416 gboolean fromEndpoint = FALSE; /* true for calls originated in Endpoints, false for calls from MGC */
2419 const mgcp_info_t *pi = (const mgcp_info_t *)MGCPinfo;
2422 if ((pi->mgcp_type == MGCP_REQUEST) && !pi->is_duplicate ) {
2423 /* check whether we already have a call with this Endpoint and it is active*/
2424 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
2427 tmp_listinfo=(voip_calls_info_t *)list->data;
2428 if ((tmp_listinfo->protocol == VOIP_MGCP) && (tmp_listinfo->call_active_state == VOIP_ACTIVE)) {
2429 tmp_mgcpinfo = (mgcp_calls_info_t *)tmp_listinfo->prot_info;
2430 if (pi->endpointId != NULL) {
2431 if (g_ascii_strcasecmp(tmp_mgcpinfo->endpointId,pi->endpointId) == 0) {
2433 check first if it is an ended call. We can still match packets to this Endpoint 2 seconds
2434 after the call has been released
2436 diff_time = nstime_to_sec(&pinfo->rel_ts) - nstime_to_sec(&tmp_listinfo->stop_rel_ts);
2437 if ( ((tmp_listinfo->call_state == VOIP_CANCELLED) ||
2438 (tmp_listinfo->call_state == VOIP_COMPLETED) ||
2439 (tmp_listinfo->call_state == VOIP_REJECTED)) &&
2442 tmp_listinfo->call_active_state = VOIP_INACTIVE;
2444 callsinfo = (voip_calls_info_t*)(list->data);
2450 list = g_list_next (list);
2453 /* there is no call with this Endpoint, lets see if this a new call or not */
2454 if (callsinfo == NULL) {
2455 if ( (strcmp(pi->code, "NTFY") == 0) && is_mgcp_signal("hd", pi->observedEvents) ) { /* off hook transition */
2456 /* this is a new call from the Endpoint */
2457 fromEndpoint = TRUE;
2459 } else if (strcmp(pi->code, "CRCX") == 0) {
2460 /* this is a new call from the MGC */
2461 fromEndpoint = FALSE;
2464 if (!newcall) return FALSE;
2466 } else if ( ((pi->mgcp_type == MGCP_RESPONSE) && pi->request_available) ||
2467 ((pi->mgcp_type == MGCP_REQUEST) && pi->is_duplicate) ) {
2468 /* if it is a response OR if it is a duplicated Request, lets look in the Graph to see
2469 if there is a request that matches */
2470 if(tapinfo->graph_analysis){
2471 listGraph = g_queue_peek_nth_link(tapinfo->graph_analysis->items, 0);
2475 gai = (seq_analysis_item_t *)listGraph->data;
2476 if (gai->fd->num == pi->req_num) {
2477 /* there is a request that match, so look the associated call with this call_num */
2478 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
2481 tmp_listinfo=(voip_calls_info_t *)list->data;
2482 if (tmp_listinfo->protocol == VOIP_MGCP) {
2483 if (tmp_listinfo->call_num == gai->conv_num) {
2484 tmp_mgcpinfo = (mgcp_calls_info_t *)tmp_listinfo->prot_info;
2485 callsinfo = (voip_calls_info_t*)(list->data);
2489 list = g_list_next (list);
2491 if (callsinfo != NULL) break;
2493 listGraph = g_list_next(listGraph);
2495 /* if there is not a matching request, just return */
2496 if (callsinfo == NULL) return FALSE;
2497 } else return FALSE;
2499 /* not in the list? then create a new entry */
2500 if (callsinfo==NULL) {
2501 callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
2502 callsinfo->call_active_state = VOIP_ACTIVE;
2503 callsinfo->call_state = VOIP_CALL_SETUP;
2505 callsinfo->from_identity=g_strdup(pi->endpointId);
2506 callsinfo->to_identity=g_strdup("");
2508 callsinfo->from_identity=g_strdup("");
2509 callsinfo->to_identity=g_strdup(pi->endpointId);
2511 COPY_ADDRESS(&(callsinfo->initial_speaker),&(pinfo->src));
2512 callsinfo->selected=FALSE;
2513 callsinfo->start_fd=pinfo->fd;
2514 callsinfo->start_rel_ts=pinfo->rel_ts;
2515 callsinfo->protocol=VOIP_MGCP;
2516 callsinfo->prot_info=g_malloc(sizeof(mgcp_calls_info_t));
2517 callsinfo->free_prot_info = g_free;
2518 tmp_mgcpinfo=(mgcp_calls_info_t *)callsinfo->prot_info;
2519 tmp_mgcpinfo->endpointId = g_strdup(pi->endpointId);
2520 tmp_mgcpinfo->fromEndpoint = fromEndpoint;
2521 callsinfo->npackets = 0;
2522 callsinfo->call_num = tapinfo->ncalls++;
2523 g_queue_push_tail(tapinfo->callsinfos, callsinfo);
2526 g_assert(tmp_mgcpinfo != NULL);
2528 /* change call state and add to graph */
2529 switch (pi->mgcp_type)
2532 if ( (strcmp(pi->code, "NTFY") == 0) && (pi->observedEvents != NULL) ) {
2533 frame_label = g_strdup_printf("%s ObsEvt:%s",pi->code, pi->observedEvents);
2535 if (tmp_mgcpinfo->fromEndpoint) {
2536 /* use the Dialed digits to fill the "To" for the call, but use the first NTFY */
2537 if (callsinfo->to_identity[0] == '\0') mgcp_dialed_digits(pi->observedEvents, &(callsinfo->to_identity));
2539 /* from MGC and the user picked up, the call is connected */
2540 } else if (is_mgcp_signal("hd", pi->observedEvents))
2541 callsinfo->call_state=VOIP_IN_CALL;
2543 /* hung up signal */
2544 if (is_mgcp_signal("hu", pi->observedEvents)) {
2545 if ((callsinfo->call_state == VOIP_CALL_SETUP) || (callsinfo->call_state == VOIP_RINGING)) {
2546 callsinfo->call_state = VOIP_CANCELLED;
2548 callsinfo->call_state = VOIP_COMPLETED;
2552 } else if (strcmp(pi->code, "RQNT") == 0) {
2553 /* for calls from Endpoint: if there is a "no signal" RQNT and the call was RINGING, we assume this is the CONNECT */
2554 if ( tmp_mgcpinfo->fromEndpoint && is_mgcp_signal("", pi->signalReq) && (callsinfo->call_state == VOIP_RINGING) ) {
2555 callsinfo->call_state = VOIP_IN_CALL;
2558 /* if there is ringback or ring tone, change state to ringing */
2559 if ( is_mgcp_signal("rg", pi->signalReq) || is_mgcp_signal("rt", pi->signalReq) ) {
2560 callsinfo->call_state = VOIP_RINGING;
2563 /* if there is a Busy or ReorderTone, and the call was Ringing or Setup the call is Rejected */
2564 if ( (is_mgcp_signal("ro", pi->signalReq) || is_mgcp_signal("bz", pi->signalReq)) && ((callsinfo->call_state == VOIP_CALL_SETUP) || (callsinfo->call_state == VOIP_RINGING)) ) {
2565 callsinfo->call_state = VOIP_REJECTED;
2568 if (pi->signalReq != NULL)
2569 frame_label = g_strdup_printf("%s%sSigReq:%s",pi->code, (pi->hasDigitMap == TRUE)?" DigitMap ":"", pi->signalReq);
2571 frame_label = g_strdup_printf("%s%s",pi->code, (pi->hasDigitMap == TRUE)?" DigitMap ":"");
2573 /* use the CallerID info to fill the "From" for the call */
2574 if (!tmp_mgcpinfo->fromEndpoint) mgcp_caller_id(pi->signalReq, &(callsinfo->from_identity));
2576 } else if (strcmp(pi->code, "DLCX") == 0) {
2578 if there is a DLCX in a call To an Endpoint and the call was not connected, we use
2579 the DLCX as the end of the call
2581 if (!tmp_mgcpinfo->fromEndpoint) {
2582 if ((callsinfo->call_state == VOIP_CALL_SETUP) || (callsinfo->call_state == VOIP_RINGING)) {
2583 callsinfo->call_state = VOIP_CANCELLED;
2588 if (frame_label == NULL) frame_label = g_strdup(pi->code);
2591 frame_label = g_strdup_printf("%u (%s)",pi->rspcode, pi->code);
2594 /* XXX what to do? */
2598 comment = g_strdup_printf("MGCP %s %s%s", tmp_mgcpinfo->endpointId, (pi->mgcp_type == MGCP_REQUEST)?"Request":"Response", pi->is_duplicate?" Duplicate":"");
2600 callsinfo->stop_fd = pinfo->fd;
2601 callsinfo->stop_rel_ts = pinfo->rel_ts;
2602 ++(callsinfo->npackets);
2603 /* increment the packets counter of all calls */
2604 ++(tapinfo->npackets);
2606 /* add to the graph */
2607 add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
2609 g_free(frame_label);
2611 /* add SDP info if apply */
2612 if ( (tapinfo->sdp_summary != NULL) && (tapinfo->sdp_frame_num == pinfo->fd->num) ) {
2613 append_to_frame_graph(tapinfo, pinfo->fd->num, tapinfo->sdp_summary, NULL);
2614 g_free(tapinfo->sdp_summary);
2615 tapinfo->sdp_summary = NULL;
2618 tapinfo->redraw = TRUE;
2620 return TRUE; /* refresh output */
2624 /****************************************************************************/
2626 /****************************************************************************/
2628 mgcp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
2630 GString *error_string;
2633 * We set TL_REQUIRES_PROTO_TREE to force a non-null "tree"
2634 * in the MGCP dissector; otherwise, the dissector
2635 * doesn't fill in the info passed to the tap's packet
2638 error_string = register_tap_listener("mgcp",
2639 tap_base_to_id(tap_id_base, tap_id_offset_mgcp_),
2641 TL_REQUIRES_PROTO_TREE,
2646 if (error_string != NULL) {
2647 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2648 "%s", error_string->str);
2649 g_string_free(error_string, TRUE);
2653 /****************************************************************************/
2655 remove_tap_listener_mgcp_calls(voip_calls_tapinfo_t *tap_id_base)
2657 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_mgcp_));
2660 /****************************************************************************/
2661 /****************************TAP for ACTRACE (AudioCodes trace)**************/
2662 /****************************************************************************/
2664 /* whenever a ACTRACE packet is seen by the tap listener */
2666 actrace_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *ACTRACEinfo)
2668 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_actrace_);
2669 const actrace_info_t *pi = (const actrace_info_t *)ACTRACEinfo;
2671 actrace_cas_calls_info_t *tmp_actrace_cas_info;
2672 voip_calls_info_t *tmp_listinfo;
2673 voip_calls_info_t *callsinfo = NULL;
2675 tapinfo->actrace_frame_num = pinfo->fd->num;
2676 tapinfo->actrace_trunk = pi->trunk;
2677 tapinfo->actrace_direction = pi->direction;
2679 if (pi->type == 1) { /* is CAS protocol */
2681 gchar *comment = NULL;
2684 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
2687 tmp_listinfo=(voip_calls_info_t *)list->data;
2688 if ( tmp_listinfo->protocol == VOIP_AC_CAS ) {
2689 tmp_actrace_cas_info = (actrace_cas_calls_info_t *)tmp_listinfo->prot_info;
2690 /* TODO: Also check the IP of the Blade, and if the call is complete (no active) */
2691 if ( (tmp_actrace_cas_info->bchannel == pi->cas_bchannel) && (tmp_actrace_cas_info->trunk == tapinfo->actrace_trunk) ) {
2692 callsinfo = (voip_calls_info_t*)(list->data);
2696 list = g_list_next (list);
2699 SET_ADDRESS(&pstn_add, AT_STRINGZ, 5, "PSTN");
2701 /* if it is a new call, add it to the list */
2703 callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
2704 callsinfo->call_active_state = VOIP_ACTIVE;
2705 callsinfo->call_state = VOIP_CALL_SETUP;
2706 callsinfo->from_identity=g_strdup("N/A");
2707 callsinfo->to_identity=g_strdup("N/A");
2708 COPY_ADDRESS(&(callsinfo->initial_speaker),tapinfo->actrace_direction?&pstn_add:&(pinfo->src));
2709 callsinfo->selected=FALSE;
2710 callsinfo->start_fd=pinfo->fd;
2711 callsinfo->start_rel_ts=pinfo->rel_ts;
2712 callsinfo->protocol=VOIP_AC_CAS;
2713 callsinfo->prot_info=g_malloc(sizeof(actrace_cas_calls_info_t));
2714 callsinfo->free_prot_info = g_free;
2716 tmp_actrace_cas_info=(actrace_cas_calls_info_t *)callsinfo->prot_info;
2717 tmp_actrace_cas_info->bchannel=pi->cas_bchannel;
2718 tmp_actrace_cas_info->trunk=tapinfo->actrace_trunk;
2719 callsinfo->npackets = 0;
2720 callsinfo->call_num = tapinfo->ncalls++;
2721 g_queue_push_tail(tapinfo->callsinfos, callsinfo);
2724 callsinfo->stop_fd = pinfo->fd;
2725 callsinfo->stop_rel_ts = pinfo->rel_ts;
2726 ++(callsinfo->npackets);
2727 /* increment the packets counter of all calls */
2728 ++(tapinfo->npackets);
2730 comment = g_strdup_printf("AC_CAS trunk:%u", tapinfo->actrace_trunk);
2732 add_to_graph(tapinfo, pinfo, edt, pi->cas_frame_label, comment, callsinfo->call_num,
2733 tapinfo->actrace_direction?&pstn_add:&(pinfo->src),
2734 tapinfo->actrace_direction?&(pinfo->src):&pstn_add,
2740 tapinfo->redraw = TRUE;
2742 return TRUE; /* refresh output */
2746 /****************************************************************************/
2748 /****************************************************************************/
2750 actrace_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
2752 GString *error_string;
2754 error_string = register_tap_listener("actrace", tap_base_to_id(tap_id_base, tap_id_offset_actrace_), NULL,
2757 actrace_calls_packet,
2761 if (error_string != NULL) {
2762 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2763 "%s", error_string->str);
2764 g_string_free(error_string, TRUE);
2768 /****************************************************************************/
2770 remove_tap_listener_actrace_calls(voip_calls_tapinfo_t *tap_id_base)
2772 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_actrace_));
2776 /****************************************************************************/
2777 /**************************** TAP for H248/MEGACO **********************************/
2778 /****************************************************************************/
2780 #define gcp_is_req(type) ( type == GCP_CMD_ADD_REQ || type == GCP_CMD_MOVE_REQ || type == GCP_CMD_MOD_REQ || \
2781 type == GCP_CMD_SUB_REQ || type == GCP_CMD_AUDITCAP_REQ || type == GCP_CMD_AUDITVAL_REQ || \
2782 type == GCP_CMD_NOTIFY_REQ || type == GCP_CMD_SVCCHG_REQ || type == GCP_CMD_TOPOLOGY_REQ || \
2783 type == GCP_CMD_CTX_ATTR_AUDIT_REQ )
2786 h248_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *prot_info) {
2787 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_h248_);
2788 const gcp_cmd_t *cmd = (const gcp_cmd_t *)prot_info;
2790 voip_calls_info_t *callsinfo = NULL;
2793 gchar mgw_addr[128];
2795 if (cmd->ctx->id == NULL_CONTEXT || cmd->ctx->id == ALL_CONTEXTS ) {
2799 if ( gcp_is_req(cmd->type) ) {
2800 mgw = &(pinfo->dst);
2801 mgc = &(pinfo->src);
2803 mgc = &(pinfo->dst);
2804 mgw = &(pinfo->src);
2807 address_to_str_buf(mgw, mgw_addr, 128);
2809 /* check whether we already have this context in the list */
2810 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
2813 voip_calls_info_t* tmp_listinfo = (voip_calls_info_t *)list->data;
2815 if (tmp_listinfo->protocol == TEL_H248) {
2816 if (tmp_listinfo->prot_info == cmd->ctx) {
2817 callsinfo = (voip_calls_info_t*)(list->data);
2821 list = g_list_next (list);
2824 if (callsinfo==NULL) {
2826 callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
2827 callsinfo->call_state = VOIP_NO_STATE;
2828 callsinfo->call_active_state = VOIP_ACTIVE;
2829 callsinfo->from_identity = g_strdup_printf("%s : %.8x", mgw_addr, cmd->ctx->id);
2830 callsinfo->to_identity = g_strdup("");
2831 callsinfo->prot_info = cmd->ctx;
2832 callsinfo->free_prot_info = NULL;
2834 callsinfo->npackets = 1;
2836 COPY_ADDRESS(&(callsinfo->initial_speaker), mgc);
2838 callsinfo->protocol = TEL_H248;
2839 callsinfo->call_num = tapinfo->ncalls++;
2840 callsinfo->start_fd = pinfo->fd;
2841 callsinfo->start_rel_ts = pinfo->rel_ts;
2842 callsinfo->stop_fd = pinfo->fd;
2843 callsinfo->stop_rel_ts = pinfo->rel_ts;
2845 callsinfo->selected = FALSE;
2847 g_queue_push_tail(tapinfo->callsinfos, callsinfo);
2850 GString *s = g_string_new("");
2851 gcp_terms_t *ctx_term;
2853 g_free(callsinfo->from_identity);
2854 callsinfo->from_identity = g_strdup_printf("%s : %.8x", mgw_addr, ((gcp_ctx_t*)callsinfo->prot_info)->id);
2856 g_free(callsinfo->to_identity);
2858 for (ctx_term = ((gcp_ctx_t*)callsinfo->prot_info)->terms.next;
2860 ctx_term = ctx_term->next ) {
2861 if ( ctx_term->term && ctx_term->term->str) {
2862 g_string_append_printf(s," %s",ctx_term->term->str);
2866 callsinfo->to_identity = g_string_free(s,FALSE);
2868 callsinfo->stop_fd = pinfo->fd;
2869 callsinfo->stop_rel_ts = pinfo->rel_ts;
2870 ++(callsinfo->npackets);
2873 add_to_graph(tapinfo, pinfo, edt, cmd->str ? cmd->str : "unknown Msg",
2874 wmem_strdup_printf(wmem_packet_scope(), "TrxId = %u, CtxId = %.8x",cmd->trx->id,cmd->ctx->id),
2875 callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
2877 ++(tapinfo->npackets);
2879 tapinfo->redraw = TRUE;
2885 h248_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
2887 GString *error_string;
2889 error_string = register_tap_listener("megaco", tap_base_to_id(tap_id_base, tap_id_offset_megaco_),
2896 if (error_string != NULL) {
2897 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2898 "%s", error_string->str);
2899 g_string_free(error_string, TRUE);
2902 error_string = register_tap_listener("h248", tap_base_to_id(tap_id_base, tap_id_offset_h248_),
2909 if (error_string != NULL) {
2910 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2911 "%s", error_string->str);
2912 g_string_free(error_string, TRUE);
2917 remove_tap_listener_h248_calls(voip_calls_tapinfo_t *tap_id_base)
2919 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_h248_));
2920 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_megaco_));
2923 /****************************************************************************/
2924 /**************************** TAP for SCCP and SUA **********************************/
2925 /**************************** ( RANAP and BSSAP ) **********************************/
2926 /****************************************************************************/
2928 static const voip_protocol sccp_proto_map[] = {
2933 #define SP2VP(ap) ((ap) < SCCP_PLOAD_NUM_PLOADS ? sccp_proto_map[(ap)] : TEL_SCCP)
2934 const value_string* sccp_payload_values;
2937 sccp_calls(voip_calls_tapinfo_t *tapinfo, packet_info *pinfo, epan_dissect_t *edt, const void *prot_info) {
2938 const sccp_msg_info_t* msg = (const sccp_msg_info_t *)prot_info;
2939 sccp_assoc_info_t* assoc = msg->data.co.assoc;
2941 voip_calls_info_t *callsinfo = NULL;
2942 gchar *label = NULL;
2943 const gchar *comment = NULL;
2944 /* check whether we already have this assoc in the list */
2946 for(list = g_queue_peek_nth_link(tapinfo->callsinfos, 0) ; list ; list = g_list_next (list) ) {
2947 if ( ((voip_calls_info_t*)(list->data))->prot_info == assoc ) {
2948 callsinfo = (voip_calls_info_t*)(list->data);
2953 if (callsinfo==NULL) {
2954 callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
2955 callsinfo->call_state = VOIP_CALL_SETUP;
2956 callsinfo->call_active_state = VOIP_ACTIVE;
2957 if ( assoc->calling_party ) {
2958 callsinfo->from_identity = g_strdup(assoc->calling_party);
2960 callsinfo->from_identity = g_strdup("Unknown");
2963 if ( assoc->called_party ) {
2964 callsinfo->to_identity = g_strdup(assoc->called_party);
2966 callsinfo->to_identity = g_strdup("Unknown");
2969 callsinfo->prot_info = (void*)assoc;
2970 callsinfo->free_prot_info = NULL;
2972 callsinfo->npackets = 1;
2974 COPY_ADDRESS(&(callsinfo->initial_speaker), &(pinfo->src));
2976 callsinfo->protocol = SP2VP(assoc->payload);
2977 /* Store frame data which holds time and frame number */
2978 callsinfo->start_fd = pinfo->fd;
2979 callsinfo->start_rel_ts = pinfo->rel_ts;
2980 callsinfo->stop_fd = pinfo->fd;
2981 callsinfo->stop_rel_ts = pinfo->rel_ts;
2983 callsinfo->selected = FALSE;
2984 callsinfo->call_num = tapinfo->ncalls++;
2986 g_queue_push_tail(tapinfo->callsinfos, callsinfo);
2989 if ( assoc->calling_party ) {
2990 g_free(callsinfo->from_identity);
2991 callsinfo->from_identity = g_strdup(assoc->calling_party);
2994 if ( assoc->called_party ) {
2995 g_free(callsinfo->to_identity);
2996 callsinfo->to_identity = g_strdup(assoc->called_party);
2999 callsinfo->protocol = SP2VP(assoc->payload);
3000 /* Store frame data which holds stop time and frame number */
3001 callsinfo->stop_fd = pinfo->fd;
3002 callsinfo->stop_rel_ts = pinfo->rel_ts;
3003 ++(callsinfo->npackets);
3005 switch (msg->type) {
3006 case SCCP_MSG_TYPE_CC:
3007 callsinfo->call_state = VOIP_IN_CALL;
3009 case SCCP_MSG_TYPE_RLC:
3010 callsinfo->call_state = VOIP_COMPLETED;
3011 callsinfo->call_active_state = VOIP_INACTIVE;
3018 if (msg->data.co.label) {
3019 label = wmem_strdup(NULL, msg->data.co.label);
3021 label = val_to_str_wmem(NULL, msg->type, sccp_payload_values, "Unknown(%d)");
3024 if (msg->data.co.comment) {
3025 comment = msg->data.co.comment;
3030 add_to_graph(tapinfo, pinfo, edt, label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3031 wmem_free(NULL, label);
3033 ++(tapinfo->npackets);
3035 tapinfo->redraw = TRUE;
3041 sccp_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *prot_info) {
3042 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sccp_);
3044 sccp_payload_values = sccp_message_type_acro_values;
3045 return sccp_calls(tapinfo, pinfo, edt, prot_info);
3050 sua_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *prot_info) {
3051 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sccp_);
3053 sccp_payload_values = sua_co_class_type_acro_values;
3054 return sccp_calls(tapinfo, pinfo, edt, prot_info);
3057 void sccp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
3059 GString *error_string;
3061 error_string = register_tap_listener("sccp", tap_base_to_id(tap_id_base, tap_id_offset_sccp_),
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("sua", tap_base_to_id(tap_id_base, tap_id_offset_sua_),
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_sccp_calls(voip_calls_tapinfo_t *tap_id_base)
3091 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_sccp_));
3092 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_sua_));
3096 /****************************************************************************/
3097 /****************************TAP for UNISTIM ********************************/
3098 /****************************************************************************/
3101 unistim_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *unistim_info)
3103 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_unistim_);
3104 voip_calls_info_t *tmp_listinfo;
3105 voip_calls_info_t *callsinfo = NULL;
3106 unistim_info_t *tmp_unistim_info = NULL;
3108 GString *g_tmp = NULL;
3109 const gchar *frame_label = NULL;
3110 gchar *comment = NULL;
3112 /* Fetch specific packet infos */
3113 const unistim_info_t *pi = (const unistim_info_t *)unistim_info;
3116 g_tmp = g_string_new(NULL);
3118 /* Check to see if this is a dup */
3119 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
3123 tmp_listinfo = (voip_calls_info_t *)list->data;
3125 if(tmp_listinfo->protocol == VOIP_UNISTIM) {
3127 tmp_unistim_info = (unistim_info_t *)tmp_listinfo->prot_info;
3129 /* Search by termid if possible, otherwise use ni/it ip + port.. */
3130 if(pi->termid != 0) {
3131 if(tmp_unistim_info->termid == pi->termid) {
3132 /* If the call has ended, then we can reuse it.. */
3133 if(tmp_listinfo->call_state == VOIP_COMPLETED || tmp_listinfo->call_state == VOIP_UNKNOWN) {
3136 callsinfo = (voip_calls_info_t*)(list->data);
3141 /* If no term id use ips / port to find entry */
3142 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)) {
3143 if(tmp_listinfo->call_state == VOIP_COMPLETED || tmp_listinfo->call_state == VOIP_UNKNOWN) {
3144 /* Do nothing previous call */
3146 callsinfo = (voip_calls_info_t*)(list->data);
3150 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)) {
3151 if(tmp_listinfo->call_state == VOIP_COMPLETED || tmp_listinfo->call_state == VOIP_UNKNOWN) {
3152 /* Do nothing, it ain't our call.. */
3154 callsinfo = (voip_calls_info_t*)(list->data);
3161 /* Otherwise, go to the next one.. */
3162 list = g_list_next(list);
3165 if(pi->payload_type == 2 || pi->payload_type == 1) {
3167 if(pi->key_state == 1 || pi->hook_state == 1) {
3169 /* If the user hits a button,
3170 Session will be SETUP */
3172 /* If new add to list */
3173 if (callsinfo==NULL) {
3175 callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
3176 callsinfo->call_active_state = VOIP_ACTIVE;
3177 callsinfo->call_state = VOIP_CALL_SETUP;
3178 callsinfo->from_identity=g_strdup_printf("%x",pi->termid);
3179 callsinfo->to_identity=g_strdup("UNKNOWN");
3180 COPY_ADDRESS(&(callsinfo->initial_speaker),&(pinfo->src));
3181 callsinfo->selected=FALSE;
3183 /* Set this on init of struct so in case the call doesn't complete, we'll have a ref. */
3184 /* Otherwise if the call is completed we'll have the open/close streams to ref actual call duration */
3185 /* Store frame data which holds time and frame number */
3186 callsinfo->start_fd=pinfo->fd;
3187 callsinfo->start_rel_ts=pinfo->rel_ts;
3189 callsinfo->protocol=VOIP_UNISTIM;
3190 callsinfo->prot_info=g_malloc(sizeof(unistim_info_t));
3192 tmp_unistim_info = (unistim_info_t *)callsinfo->prot_info;
3194 /* Clear tap struct */
3195 tmp_unistim_info->rudp_type = 0;
3196 tmp_unistim_info->payload_type = 0;
3197 tmp_unistim_info->sequence = pi->sequence;
3198 tmp_unistim_info->termid = pi->termid;
3199 tmp_unistim_info->key_val = -1;
3200 tmp_unistim_info->key_state = -1;
3201 tmp_unistim_info->hook_state = -1;
3202 tmp_unistim_info->stream_connect = -1;
3203 tmp_unistim_info->trans_connect = -1;
3204 tmp_unistim_info->set_termid = -1;
3205 tmp_unistim_info->string_data = NULL;
3206 tmp_unistim_info->key_buffer = NULL;
3208 COPY_ADDRESS(&(tmp_unistim_info->it_ip),&(pi->it_ip));
3209 COPY_ADDRESS(&(tmp_unistim_info->ni_ip),&(pi->ni_ip));
3210 tmp_unistim_info->it_port = pi->it_port;
3212 callsinfo->free_prot_info = g_free;
3213 callsinfo->npackets = 0;
3214 callsinfo->call_num = tapinfo->ncalls++;
3215 g_queue_push_tail(tapinfo->callsinfos, callsinfo);
3219 /* Set up call wide info struct */
3220 tmp_unistim_info = (unistim_info_t *)callsinfo->prot_info;
3221 tmp_unistim_info->sequence = pi->sequence;
3224 /* Each packet COULD BE OUR LAST!!!! */
3225 /* Store frame data which holds time and frame number */
3226 callsinfo->stop_fd = pinfo->fd;
3227 callsinfo->stop_rel_ts = pinfo->rel_ts;
3229 /* This is a valid packet so increment counter */
3230 ++(callsinfo->npackets);
3232 /* increment the packets counter of all calls */
3233 ++(tapinfo->npackets);
3235 /* Key was depressed.. update key buffer.. */
3236 if(pi->key_val >= 0 && pi->key_val <= 11) {
3238 if(tmp_unistim_info->key_buffer != NULL) {
3240 /* assign to temp variable */
3241 g_string_assign(g_tmp,tmp_unistim_info->key_buffer);
3243 /* Manipulate the data */
3244 if(pi->key_val == 10) {
3245 tmp_unistim_info->key_buffer = g_strdup_printf("%s*",g_tmp->str);
3246 } else if(pi->key_val == 11) {
3247 tmp_unistim_info->key_buffer = g_strdup_printf("%s#",g_tmp->str);
3249 tmp_unistim_info->key_buffer = g_strdup_printf("%s%d",g_tmp->str,pi->key_val);
3254 /* Create new string */
3255 if(pi->key_val == 10) {
3256 tmp_unistim_info->key_buffer = g_strdup("*");
3257 } else if(pi->key_val == 11) {
3258 tmp_unistim_info->key_buffer = g_strdup("#");
3260 tmp_unistim_info->key_buffer = g_strdup_printf("%d",pi->key_val);
3265 /* Select for non-digit characters */
3266 if(pi->key_val == 10) {
3267 comment = g_strdup_printf("Key Input Sent: * (%d)", pi->sequence);
3268 } else if(pi->key_val == 11) {
3269 comment = g_strdup_printf("Key Input Sent: # (%d)", pi->sequence);
3271 comment = g_strdup_printf("Key Input Sent: %d (%d)",pi->key_val, pi->sequence);
3273 } else if(pi->key_val == 12) {
3274 /* Set label and comment for graph */
3275 comment = g_strdup_printf("Key Input Sent: UP (%d)", pi->sequence);
3276 } else if(pi->key_val == 13) {
3277 /* Set label and comment for graph */
3278 comment = g_strdup_printf("Key Input Sent: DOWN (%d)", pi->sequence);
3279 } else if(pi->key_val == 14) {
3280 /* Set label and comment for graph */
3281 comment = g_strdup_printf("Key Input Sent: RIGHT (%d)", pi->sequence);
3282 } else if(pi->key_val == 15) {
3283 if(pi->key_buffer != NULL) {
3285 g_string_assign(g_tmp,pi->key_buffer);
3287 /* Manipulate the data */
3288 g_string_truncate(g_tmp,g_tmp->len-1);
3290 /* Insert new data */
3291 tmp_unistim_info->key_buffer = g_strdup(g_tmp->str);
3294 /* Set label and comment for graph */
3295 comment = g_strdup_printf("Key Input Sent: LEFT (%d)", pi->sequence);
3296 } else if(pi->key_val == 20) {
3297 /* User pressed the soft key 0 probably dial */
3298 comment = g_strdup_printf("Key Input Sent: S0 (%d)", pi->sequence);
3299 } else if(pi->key_val == 21) {
3300 /* User pressed the soft key 1 */
3301 comment = g_strdup_printf("Key Input Sent: S1 (%d)", pi->sequence);
3302 } else if(pi->key_val == 22) {
3303 /* User pressed the soft key 2 */
3304 /* On cs2k phones, soft key 2 is backspace. */
3305 if(pi->key_buffer != NULL) {
3308 g_string_assign(g_tmp,pi->key_buffer);
3310 /* Manipulate the data */
3311 g_string_truncate(g_tmp,g_tmp->len-1);
3313 /* Insert new data */
3314 tmp_unistim_info->key_buffer = g_strdup(g_tmp->str);
3317 /* add label and comment */
3318 comment = g_strdup_printf("Key Input Sent: S2 (%d)", pi->sequence);
3319 } else if(pi->key_val == 28) {
3320 /* User pressed something */
3321 comment = g_strdup_printf("Key Input Sent: Release (%d)", pi->sequence);
3322 } else if(pi->key_val == 23) {
3323 /* User pressed the soft key 3 */
3324 /* Cancel on cs2k so clear buffer */
3325 /* On mcs it's config which will clear the buffer too */
3326 tmp_unistim_info->key_buffer = g_strdup("\n");
3328 /* User pressed something, set labels*/
3329 comment = g_strdup_printf("Key Input Sent: S3 (%d)", pi->sequence);
3330 } else if(pi->key_val == 27) {
3331 /* User pressed something */
3332 comment = g_strdup_printf("Key Input Sent: Hold (%d)", pi->sequence);
3333 } else if(pi->key_val == 29) {
3334 /* User pressed something */
3335 comment = g_strdup_printf("Key Input Sent: Mute (%d)", pi->sequence);
3336 } else if(pi->key_val == 30) {
3337 /* User pressed something */
3338 comment = g_strdup_printf("Key Input Sent: Headset (%d)", pi->sequence);
3339 } else if(pi->key_val == 31) {
3340 /* Handsfree button */
3341 comment = g_strdup_printf("Key Input Sent: Handsfree (%d)", pi->sequence);
3342 } else if(pi->key_val >= 32 && pi->key_val <= 56) {
3344 comment = g_strdup_printf("Key Input Sent: Prog%d (%d)", (pi->key_val & 31), pi->sequence);
3347 if(pi->key_val != -1) {
3349 frame_label = "KEY INPUT";
3351 if (comment == NULL)
3352 /* Ouch! What do you do!? */
3353 /* User pressed something */
3354 comment = g_strdup_printf("Key Input Sent: UNKNOWN - %d (%d)", pi->key_val, pi->sequence);
3356 /* add to the graph */
3357 add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3362 if(pi->hook_state == 1) {
3364 /* Phone is off hook */
3365 frame_label = "OFF HOOK";
3366 comment = g_strdup_printf("Off Hook (%d)", pi->sequence);
3368 /* add to the graph */
3369 add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3372 } else if(pi->hook_state == 0) {
3374 /* Phone is on hook */
3375 frame_label = "ON HOOK";
3376 comment = g_strdup_printf("On Hook (%d)", pi->sequence);
3378 /* add to the graph */
3379 add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3385 /* Open stream was sent from server */
3386 if(pi->stream_connect == 1 && callsinfo != NULL) {
3389 /* Signifies the start of the call so set start_sec & start_usec */
3390 /* Frame data holds the time info */
3391 callsinfo->start_fd=pinfo->fd;
3392 callsinfo->start_rel_ts=pinfo->rel_ts;
3393 /* Each packet COULD BE OUR LAST!!!! */
3394 /* Store frame data which holds time and frame number */
3395 callsinfo->stop_fd = pinfo->fd;
3396 callsinfo->stop_rel_ts = pinfo->rel_ts;
3398 /* Local packets too */
3399 ++(callsinfo->npackets);
3401 /* increment the packets counter of all calls */
3402 ++(tapinfo->npackets);
3404 /* ?? means we're not quite sure if this is accurate. Since Unistim isn't a true
3405 Call control protocol, we can only guess at the destination by messing with
3407 if(tmp_unistim_info->key_buffer != NULL) {
3408 callsinfo->to_identity = g_strdup_printf("?? %s",tmp_unistim_info->key_buffer);
3411 /* change sequence number for ACK detection */
3412 tmp_unistim_info->sequence = pi->sequence;
3414 /* State changes too */
3415 callsinfo->call_active_state = VOIP_ACTIVE;
3416 callsinfo->call_state = VOIP_IN_CALL;
3418 /* Add graph data */
3419 frame_label = "STREAM OPENED";
3420 comment = g_strdup_printf("Stream Opened (%d)",pi->sequence);
3422 /* add to the graph */
3423 add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3425 } else if(pi->stream_connect == 1 && callsinfo == NULL) {
3427 /* Research indicates some nortel products initiate stream first
3428 * without keypresses. therefore creating this solely on a keypress is
3430 * Sometimes calls start immediately with open stream.
3432 callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
3433 callsinfo->call_active_state = VOIP_ACTIVE;
3434 callsinfo->call_state = VOIP_CALL_SETUP;
3435 callsinfo->from_identity=g_strdup("UNKNOWN");
3436 callsinfo->to_identity=g_strdup("UNKNOWN");
3437 COPY_ADDRESS(&(callsinfo->initial_speaker),&(pinfo->src));
3438 callsinfo->selected=FALSE;
3440 /* Set this on init of struct so in case the call doesn't complete, we'll have a ref. */
3441 /* Otherwise if the call is completed we'll have the open/close streams to ref actual call duration */
3442 callsinfo->start_fd=pinfo->fd;
3443 callsinfo->start_rel_ts=pinfo->rel_ts;
3445 callsinfo->protocol=VOIP_UNISTIM;
3446 callsinfo->prot_info=g_malloc(sizeof(unistim_info_t));
3448 tmp_unistim_info = (unistim_info_t *)callsinfo->prot_info;
3450 /* Clear tap struct */
3451 tmp_unistim_info->rudp_type = 0;
3452 tmp_unistim_info->payload_type = 0;
3453 tmp_unistim_info->sequence = pi->sequence;
3454 tmp_unistim_info->termid = 0;
3455 tmp_unistim_info->key_val = -1;
3456 tmp_unistim_info->key_state = -1;
3457 tmp_unistim_info->hook_state = -1;
3458 tmp_unistim_info->stream_connect = -1;
3459 tmp_unistim_info->trans_connect = -1;
3460 tmp_unistim_info->set_termid = -1;
3461 tmp_unistim_info->string_data = NULL;
3462 tmp_unistim_info->key_buffer = NULL;
3464 COPY_ADDRESS(&(tmp_unistim_info->it_ip),&(pi->it_ip));
3465 COPY_ADDRESS(&(tmp_unistim_info->ni_ip),&(pi->ni_ip));
3466 tmp_unistim_info->it_port = pi->it_port;
3468 callsinfo->free_prot_info = g_free;
3469 callsinfo->npackets = 0;
3470 callsinfo->call_num = tapinfo->ncalls++;
3471 g_queue_push_tail(tapinfo->callsinfos, callsinfo);
3474 /* Each packet COULD BE OUR LAST!!!! */
3475 /* Store frame data which holds time and frame number */
3476 callsinfo->stop_fd = pinfo->fd;
3477 callsinfo->stop_rel_ts = pinfo->rel_ts;
3478 /* Local packets too */
3479 ++(callsinfo->npackets);
3481 /* increment the packets counter of all calls */
3482 ++(tapinfo->npackets);
3484 /* ?? means we're not quite sure if this is accurate. Since Unistim isn't a true
3485 Call control protocol, we can only guess at the destination by messing with
3487 if(tmp_unistim_info->key_buffer != NULL) {
3488 callsinfo->to_identity = g_strdup_printf("?? %s",tmp_unistim_info->key_buffer);
3491 /* change sequence number for ACK detection */
3492 tmp_unistim_info->sequence = pi->sequence;
3494 /* State changes too */
3495 callsinfo->call_active_state = VOIP_ACTIVE;
3496 callsinfo->call_state = VOIP_IN_CALL;
3498 /* Add graph data */
3499 frame_label = "STREAM OPENED";
3500 comment = g_strdup_printf("Stream Opened (%d)",pi->sequence);
3502 /* add to the graph */
3503 add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3505 } else if(pi->stream_connect == 0 && callsinfo != NULL) {
3508 /* Set stop seconds + usec */
3509 /* frame_data holds the time info */
3510 callsinfo->stop_fd = pinfo->fd;
3511 callsinfo->stop_rel_ts = pinfo->rel_ts;
3513 tmp_unistim_info->sequence = pi->sequence;
3515 if(callsinfo->call_state == VOIP_IN_CALL) {
3516 callsinfo->call_active_state = VOIP_INACTIVE;
3517 callsinfo->call_state = VOIP_COMPLETED;
3519 callsinfo->call_state = VOIP_UNKNOWN;
3520 callsinfo->call_active_state = VOIP_INACTIVE;
3523 frame_label = "STREAM CLOSED";
3524 comment = g_strdup_printf("Stream Closed (%d)",pi->sequence);
3526 /* add to the graph */
3527 add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3532 } else if(pi->rudp_type == 1 && callsinfo != NULL) {
3534 /* Only show acks for processed seq #s */
3535 if(tmp_unistim_info->sequence == pi->sequence) {
3537 frame_label = "ACK";
3538 comment = g_strdup_printf("ACK for sequence %d",pi->sequence);
3540 /* add to the graph */
3541 add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3545 } else if(pi->rudp_type == 0 && callsinfo != NULL) {
3548 frame_label = "NAK";
3549 comment = g_strdup_printf("NAK for sequence %d",pi->sequence);
3551 /* add to the graph */
3552 add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3559 tapinfo->redraw = TRUE;
3564 /****************************************************************************/
3566 /****************************************************************************/
3568 unistim_calls_init_tap(voip_calls_tapinfo_t *tap_id_base) {
3570 GString *error_string;
3572 error_string = register_tap_listener("unistim", tap_base_to_id(tap_id_base, tap_id_offset_unistim_),
3576 unistim_calls_packet,
3580 if (error_string != NULL) {
3581 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3582 "%s", error_string->str);
3583 g_string_free(error_string, TRUE);
3587 /****************************************************************************/
3589 remove_tap_listener_unistim_calls(voip_calls_tapinfo_t *tap_id_base)
3591 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_unistim_));
3594 /****************************************************************************/
3595 /* ***************************TAP for SKINNY **********************************/
3596 /****************************************************************************/
3598 /* Telecaster to tap-voip call state mapping */
3599 static const voip_call_state skinny_tap_voip_state[] = {
3618 skinny_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *skinny_info)
3620 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_skinny_);
3622 voip_calls_info_t *callsinfo = NULL;
3624 const skinny_info_t *si = (const skinny_info_t *)skinny_info;
3625 skinny_calls_info_t *tmp_skinnyinfo;
3628 if (si == NULL || (si->callId == 0 && si->passThruId == 0))
3630 /* check whether we already have this context in the list */
3631 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
3634 voip_calls_info_t* tmp_listinfo = (voip_calls_info_t *)list->data;
3635 if (tmp_listinfo->protocol == VOIP_SKINNY) {
3636 tmp_skinnyinfo = (skinny_calls_info_t *)tmp_listinfo->prot_info;
3637 if (tmp_skinnyinfo->callId == si->callId ||
3638 tmp_skinnyinfo->callId == si->passThruId) {
3639 callsinfo = (voip_calls_info_t*)(list->data);
3643 list = g_list_next (list);
3646 if (si->messId >= 256)
3647 phone = &(pinfo->dst);
3649 phone = &(pinfo->src);
3651 if (callsinfo==NULL) {
3652 callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
3653 callsinfo->call_state = VOIP_NO_STATE;
3654 callsinfo->call_active_state = VOIP_ACTIVE;
3655 /* callsinfo->from_identity = g_strdup_printf("%s : %.8x", "Skinny", 1); */
3656 callsinfo->from_identity = g_strdup("");
3657 callsinfo->to_identity = g_strdup("");
3658 callsinfo->prot_info = g_malloc(sizeof(skinny_calls_info_t));
3659 callsinfo->free_prot_info = g_free;
3660 tmp_skinnyinfo = (skinny_calls_info_t *)callsinfo->prot_info;
3661 tmp_skinnyinfo->callId = si->callId ? si->callId : si->passThruId;
3662 callsinfo->npackets = 1;
3664 COPY_ADDRESS(&(callsinfo->initial_speaker), phone);
3666 callsinfo->protocol = VOIP_SKINNY;
3667 callsinfo->call_num = tapinfo->ncalls++;
3668 callsinfo->start_fd = pinfo->fd;
3669 callsinfo->start_rel_ts = pinfo->rel_ts;
3670 callsinfo->stop_fd = pinfo->fd;
3671 callsinfo->stop_rel_ts = pinfo->rel_ts;
3673 callsinfo->selected = FALSE;
3674 g_queue_push_tail(tapinfo->callsinfos, callsinfo);
3676 if (si->callingParty) {
3677 g_free(callsinfo->from_identity);
3678 callsinfo->from_identity = g_strdup(si->callingParty);
3680 if (si->calledParty) {
3681 g_free(callsinfo->to_identity);
3682 callsinfo->to_identity = g_strdup(si->calledParty);
3684 if ((si->callState > 0) && (si->callState < (sizeof(skinny_tap_voip_state)/sizeof(skinny_tap_voip_state[0]))))
3685 callsinfo->call_state = skinny_tap_voip_state[si->callState];
3687 callsinfo->stop_fd = pinfo->fd;
3688 callsinfo->stop_rel_ts = pinfo->rel_ts;
3689 ++(callsinfo->npackets);
3694 comment = g_strdup_printf("CallId = %u, PTId = %u", si->callId, si->passThruId);
3696 comment = g_strdup_printf("CallId = %u, LineId = %u", si->callId, si->lineId);
3699 comment = g_strdup_printf("PTId = %u", si->passThruId);
3704 add_to_graph(tapinfo, pinfo, edt, si->messageName, comment,
3705 callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3712 /****************************************************************************/
3714 /****************************************************************************/
3716 skinny_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
3718 GString *error_string;
3721 * We set TL_REQUIRES_PROTO_TREE to force a non-null "tree"
3722 * in the SKINNY dissector; otherwise, the dissector
3723 * doesn't fill in the info passed to the tap's packet
3726 error_string = register_tap_listener("skinny",
3727 tap_base_to_id(tap_id_base, tap_id_offset_skinny_),
3729 TL_REQUIRES_PROTO_TREE,
3731 skinny_calls_packet,
3734 if (error_string != NULL) {
3735 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3736 "%s", error_string->str);
3737 g_string_free(error_string, TRUE);
3741 /****************************************************************************/
3743 remove_tap_listener_skinny_calls(voip_calls_tapinfo_t *tap_id_base)
3745 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_skinny_));
3748 /****************************************************************************/
3749 /* ***************************TAP for IAX2 **********************************/
3750 /****************************************************************************/
3752 static void free_iax2_info(gpointer p) {
3753 iax2_info_t *ii = (iax2_info_t *)p;
3759 /****************************************************************************/
3760 /* whenever a IAX2 packet is seen by the tap listener */
3762 iax2_calls_packet( void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *iax2_info)
3764 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_iax2_);
3766 voip_calls_info_t *callsinfo = NULL;
3768 const iax2_info_t *ii = (const iax2_info_t *)iax2_info;
3769 iax2_info_t *tmp_iax2info;
3771 if (ii == NULL || ii->ptype != IAX2_FULL_PACKET || (ii->scallno == 0 && ii->dcallno == 0))
3773 /* check whether we already have this context in the list */
3774 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
3777 voip_calls_info_t* tmp_listinfo = (voip_calls_info_t *)list->data;
3778 if (tmp_listinfo->protocol == VOIP_IAX2) {
3779 tmp_iax2info = (iax2_info_t *)tmp_listinfo->prot_info;
3780 if (tmp_iax2info->scallno == ii->scallno ||
3781 tmp_iax2info->scallno == ii->dcallno) {
3782 callsinfo = (voip_calls_info_t*)(list->data);
3786 list = g_list_next (list);
3788 phone = &(pinfo->src);
3791 if (callsinfo==NULL) {
3792 /* We only care about real calls, i.e., no registration stuff */
3793 if (ii->ftype != AST_FRAME_IAX || ii->csub != IAX_COMMAND_NEW)
3795 callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
3796 callsinfo->call_state = VOIP_NO_STATE;
3797 callsinfo->call_active_state = VOIP_ACTIVE;
3798 callsinfo->prot_info=g_malloc(sizeof(iax2_info_t));
3799 callsinfo->free_prot_info = free_iax2_info;
3800 tmp_iax2info = (iax2_info_t *)callsinfo->prot_info;
3802 tmp_iax2info->scallno = ii->scallno;
3803 if (tmp_iax2info->scallno == 0) tmp_iax2info->scallno = ii->dcallno;
3804 tmp_iax2info->callState = ii->callState;
3806 callsinfo->npackets = 1;
3808 COPY_ADDRESS(&(callsinfo->initial_speaker), phone);
3809 callsinfo->from_identity = g_strdup(ii->callingParty);
3810 callsinfo->to_identity = g_strdup(ii->calledParty);
3812 callsinfo->protocol = VOIP_IAX2;
3813 callsinfo->call_num = tapinfo->ncalls++;
3814 callsinfo->start_fd=pinfo->fd;
3815 callsinfo->start_rel_ts=pinfo->rel_ts;
3816 callsinfo->stop_fd = pinfo->fd;
3817 callsinfo->stop_rel_ts = pinfo->rel_ts;
3819 callsinfo->selected = FALSE;
3820 g_queue_push_tail(tapinfo->callsinfos, callsinfo);
3823 callsinfo->call_state = ii->callState;
3825 callsinfo->stop_fd = pinfo->fd;
3826 callsinfo->stop_rel_ts = pinfo->rel_ts;
3827 ++(callsinfo->npackets);
3830 add_to_graph(tapinfo, pinfo, edt, ii->messageName, "",
3831 callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3838 /****************************************************************************/
3840 /****************************************************************************/
3842 iax2_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
3844 GString *error_string;
3847 * We set TL_REQUIRES_PROTO_TREE to force a non-null "tree"
3848 * in the IAX2 dissector; otherwise, the dissector
3849 * doesn't fill in the info passed to the tap's packet
3851 * XXX - that appears to be true of the MGCP and SKINNY
3852 * dissectors, but, unless I've missed something, it doesn't
3853 * appear to be true of the IAX2 dissector.
3855 error_string = register_tap_listener("IAX2",
3856 tap_base_to_id(tap_id_base, tap_id_offset_iax2_),
3858 TL_REQUIRES_PROTO_TREE,
3863 if (error_string != NULL) {
3864 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s",
3866 g_string_free(error_string, TRUE);
3870 /****************************************************************************/
3872 remove_tap_listener_iax2_calls(voip_calls_tapinfo_t *tap_id_base)
3874 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_iax2_));
3877 /****************************************************************************/
3878 /* ***************************TAP for OTHER PROTOCOL **********************************/
3879 /****************************************************************************/
3882 voip_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *VoIPinfo)
3884 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_voip_);
3885 voip_calls_info_t *callsinfo = NULL;
3886 voip_calls_info_t *tmp_listinfo;
3888 const voip_packet_info_t *pi = (const voip_packet_info_t *)VoIPinfo;
3891 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
3893 tmp_listinfo = (voip_calls_info_t *)list->data;
3894 if ( tmp_listinfo->protocol == VOIP_COMMON ) {
3895 if (!strcmp(pi->call_id, tmp_listinfo->call_id)) {
3896 callsinfo = (voip_calls_info_t*)(list->data);
3900 list = g_list_next(list);
3903 if (callsinfo == NULL) {
3904 callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
3905 callsinfo->call_active_state = pi->call_active_state;
3906 callsinfo->call_state = pi->call_state;
3907 callsinfo->call_id=g_strdup((pi->call_id)?pi->call_id:"");
3908 callsinfo->from_identity = g_strdup((pi->from_identity)?pi->from_identity:"");
3909 callsinfo->to_identity = g_strdup((pi->to_identity)?pi->to_identity:"");
3910 COPY_ADDRESS(&(callsinfo->initial_speaker),&(pinfo->src));
3911 callsinfo->selected=FALSE;
3912 callsinfo->start_fd=pinfo->fd;
3913 callsinfo->start_rel_ts=pinfo->rel_ts;
3914 callsinfo->protocol=VOIP_COMMON;
3915 callsinfo->protocol_name=g_strdup((pi->protocol_name)?pi->protocol_name:"");
3916 callsinfo->call_comment=g_strdup((pi->call_comment)?pi->call_comment:"");
3917 callsinfo->prot_info=NULL;
3918 callsinfo->free_prot_info = NULL;
3920 callsinfo->call_num = tapinfo->ncalls++;
3921 callsinfo->npackets = 0;
3923 g_queue_push_tail(tapinfo->callsinfos, callsinfo);
3926 callsinfo->call_active_state = pi->call_active_state;
3927 if ((callsinfo->call_state != VOIP_COMPLETED) && (pi->call_state == VOIP_COMPLETED))
3928 tapinfo->completed_calls++;
3929 if (pi->call_state != VOIP_NO_STATE)
3930 callsinfo->call_state = pi->call_state;
3931 if (pi->call_comment) {
3932 g_free(callsinfo->call_comment);
3933 callsinfo->call_comment=g_strdup(pi->call_comment);
3935 callsinfo->stop_fd = pinfo->fd;
3936 callsinfo->stop_rel_ts = pinfo->rel_ts;
3937 ++(callsinfo->npackets);
3938 ++(tapinfo->npackets);
3940 /* add to the graph */
3941 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);
3943 tapinfo->redraw = TRUE;
3947 /****************************************************************************/
3950 voip_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
3952 GString *error_string;
3954 error_string = register_tap_listener("voip", tap_base_to_id(tap_id_base, tap_id_offset_voip_),
3962 if (error_string != NULL) {
3963 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3964 "%s", error_string->str);
3965 g_string_free(error_string, TRUE);
3969 /****************************************************************************/
3971 remove_tap_listener_voip_calls(voip_calls_tapinfo_t *tap_id_base)
3973 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_voip_));
3976 /****************************************************************************/
3977 /* ***************************TAP for OTHER PROTOCOL **********************************/
3978 /****************************************************************************/
3980 /****************************************************************************/
3981 /* whenever a prot_ packet is seen by the tap listener */
3984 prot_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt _U_, const void *prot_info _U_)
3986 voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_prot_);
3987 if (callsinfo!=NULL) {
3988 callsinfo->stop_abs = pinfo->fd->abs_ts;
3989 callsinfo->stop_rel = pinfo->rel_ts;
3990 callsinfo->last_frame_num=pinfo->fd->num;
3991 ++(callsinfo->npackets);
3992 ++(tapinfo->npackets);
3995 tapinfo->redraw = TRUE;
4001 /****************************************************************************/
4004 prot_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
4006 GString *error_string;
4008 error_string = register_tap_listener("prot_", tap_base_to_id(tap_id_base, tap_id_offset_prot_),
4016 if (error_string != NULL) {
4017 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4018 "%s", error_string->str);
4019 g_string_free(error_string, TRUE);
4024 /****************************************************************************/
4027 remove_tap_listener_prot__calls(voip_calls_tapinfo_t *tap_id_base)
4029 remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_prot_));
4034 * Editor modelines - https://www.wireshark.org/tools/modelines.html
4039 * indent-tabs-mode: nil
4042 * ex: set shiftwidth=4 tabstop=8 expandtab:
4043 * :indentSize=4:tabSize=8:noTabs=true: