GTK3 typo fixes:
[obnox/wireshark/wip.git] / gtk / voip_calls.c
1 /* voip_calls.c
2  * VoIP calls summary addition for Wireshark
3  *
4  * $Id$
5  *
6  * Copyright 2004, Ericsson, Spain
7  * By Francisco Alcoba <francisco.alcoba@ericsson.com>
8  *
9  * based on h323_calls.c
10  * Copyright 2004, Iskratel, Ltd, Kranj
11  * By Miha Jemec <m.jemec@iskratel.si>
12  *
13  * H323, RTP, RTP Event, MGCP, AudioCodes (ISDN PRI and CAS), T38 and Graph Support
14  * By Alejandro Vaquero, alejandro.vaquero@verso.com
15  * Copyright 2005, Verso Technologies Inc.
16  *
17  * Wireshark - Network traffic analyzer
18  * By Gerald Combs <gerald@wireshark.org>
19  * Copyright 1998 Gerald Combs
20  *
21  * This program is free software; you can redistribute it and/or
22  * modify it under the terms of the GNU General Public License
23  * as published by the Free Software Foundation; either version 2
24  * of the License, or (at your option) any later version.
25  *
26  * This program is distributed in the hope that it will be useful,
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29  * GNU General Public License for more details.
30  *
31  * You should have received a copy of the GNU General Public License
32  * along with this program; if not, write to the Free Software
33  * Foundation,  Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
34  */
35
36 #ifdef HAVE_CONFIG_H
37 # include "config.h"
38 #endif
39 #include <string.h>
40
41 #include <epan/epan.h>
42 #include <epan/packet.h>
43 #include <epan/tap.h>
44 #include <epan/tap-voip.h>
45 #include <epan/dissectors/packet-sip.h>
46 #include <epan/dissectors/packet-mtp3.h>
47 #include <epan/dissectors/packet-isup.h>
48 #include <epan/dissectors/packet-h225.h>
49 #include <epan/dissectors/packet-h245.h>
50 #include <epan/dissectors/packet-q931.h>
51 #include <epan/dissectors/packet-sdp.h>
52 #include <epan/dissectors/packet-mgcp.h>
53 #include <epan/dissectors/packet-actrace.h>
54 #include <epan/dissectors/packet-rtp.h>
55 #include <epan/dissectors/packet-rtp-events.h>
56 #include <epan/dissectors/packet-t38.h>
57 #include <epan/dissectors/packet-t30.h>
58 #include <epan/dissectors/packet-h248.h>
59 #include <epan/dissectors/packet-sccp.h>
60 #include <plugins/unistim/packet-unistim.h>
61 #include <epan/dissectors/packet-skinny.h>
62 #include <epan/dissectors/packet-iax2.h>
63 #include <epan/rtp_pt.h>
64
65 #include "../alert_box.h"
66 #include "../simple_dialog.h"
67
68 #include "gtk/graph_analysis.h"
69 #include "gtk/voip_calls.h"
70 #include "gtk/voip_calls_dlg.h"
71 #include "gtk/main.h"
72
73 #ifdef HAVE_LIBPORTAUDIO
74 #include "gtk/rtp_player.h"
75 #endif /* HAVE_LIBPORTAUDIO */
76
77
78 const char *voip_call_state_name[8]={
79         "",
80         "CALL SETUP",
81         "RINGING",
82         "IN CALL",
83         "CANCELLED",
84         "COMPLETED",
85         "REJECTED",
86         "UNKNOWN"
87 };
88
89 /* defines whether we can consider the call active */
90 const char *voip_protocol_name[]={
91         "SIP",
92         "ISUP",
93         "H.323",
94         "MGCP",
95         "AC_ISDN",
96         "AC_CAS",
97         "T.38",
98         "H.248",
99         "SCCP",
100         "BSSMAP",
101         "RANAP",
102         "UNISTIM",
103         "SKINNY",
104         "IAX2",
105         "VoIP"
106 };
107
108 typedef struct {
109         gchar *frame_label;
110         gchar *comment;
111 } graph_str;
112
113 #define H245_MAX 6
114
115 typedef struct {
116         guint32 frame_num;
117         gint8 labels_count;
118         graph_str labels[H245_MAX];
119 } h245_labels_t;
120
121 static h245_labels_t h245_labels;
122
123 /****************************************************************************/
124 /* the one and only global voip_calls_tapinfo_t structure */
125 static voip_calls_tapinfo_t the_tapinfo_struct =
126         {0, NULL, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
127
128 /* the one and only global voip_rtp_tapinfo_t structure */
129 static voip_rtp_tapinfo_t the_tapinfo_rtp_struct =
130         {0, NULL, 0, 0};
131
132 /****************************************************************************/
133 /* when there is a [re]reading of packet's */
134 void voip_calls_reset(voip_calls_tapinfo_t *tapinfo)
135 {
136         voip_calls_info_t *callsinfo;
137         voip_rtp_tapinfo_t *rtp_tapinfo = &the_tapinfo_rtp_struct;
138         voip_rtp_stream_info_t *strinfo;
139         graph_analysis_item_t *graph_item;
140         GList *list;
141
142 #ifdef HAVE_LIBPORTAUDIO
143         /* reset the RTP player */
144         reset_rtp_player();
145 #endif
146
147         /* free the data items first */
148         list = g_list_first(tapinfo->callsinfo_list);
149         while (list)
150         {
151                 callsinfo = list->data;
152                 g_free(callsinfo->call_id);
153                 g_free(callsinfo->from_identity);
154                 g_free(callsinfo->to_identity);
155                 g_free((void *)(callsinfo->initial_speaker.data));
156                 g_free(callsinfo->protocol_name);
157                 g_free(callsinfo->call_comment);
158
159                 if (callsinfo->free_prot_info && callsinfo->prot_info)
160                         callsinfo->free_prot_info(callsinfo->prot_info);
161
162                 g_free(list->data);
163                 list = g_list_next(list);
164         }
165         g_list_free(tapinfo->callsinfo_list);
166         tapinfo->callsinfo_list = NULL;
167         tapinfo->ncalls = 0;
168         tapinfo->npackets = 0;
169         tapinfo->start_packets = 0;
170         tapinfo->completed_calls = 0;
171         tapinfo->rejected_calls = 0;
172
173         /* free the graph data items first */
174         list = g_list_first(tapinfo->graph_analysis->list);
175         while (list)
176         {
177                 graph_item = list->data;
178                 g_free(graph_item->frame_label);
179                 g_free(graph_item->comment);
180                 g_free((void *)graph_item->src_addr.data);
181                 g_free((void *)graph_item->dst_addr.data);
182                 g_free(list->data);
183                 list = g_list_next(list);
184         }
185         g_list_free(tapinfo->graph_analysis->list);
186         tapinfo->graph_analysis->nconv = 0;
187         tapinfo->graph_analysis->list = NULL;
188
189         ++(tapinfo->launch_count);
190
191         /* free the strinfo data items first */
192         list = g_list_first(rtp_tapinfo->list);
193         while(list)
194         {
195                 strinfo = list->data;
196                 g_free(strinfo->pt_str);
197                 list = g_list_next(list);
198         }
199         g_list_free(rtp_tapinfo->list);
200         rtp_tapinfo->list = NULL;
201
202         return;
203 }
204
205 /****************************************************************************/
206 void graph_analysis_data_init(void){
207         the_tapinfo_struct.graph_analysis = g_malloc(sizeof(graph_analysis_info_t));
208         the_tapinfo_struct.graph_analysis->nconv = 0;
209         the_tapinfo_struct.graph_analysis->list = NULL;
210 }
211
212 /****************************************************************************/
213 /* Add a new item into the graph */
214 static void add_to_graph(voip_calls_tapinfo_t *tapinfo _U_, packet_info *pinfo, const gchar *frame_label, const gchar *comment, guint16 call_num, address *src_addr, address *dst_addr, guint16 line_style)
215 {
216         graph_analysis_item_t *gai;
217
218         gai = g_malloc(sizeof(graph_analysis_item_t));
219         gai->frame_num = pinfo->fd->num;
220         gai->time= nstime_to_sec(&pinfo->fd->rel_ts);
221         COPY_ADDRESS(&(gai->src_addr),src_addr);
222         COPY_ADDRESS(&(gai->dst_addr),dst_addr);
223
224         gai->port_src=pinfo->srcport;
225         gai->port_dst=pinfo->destport;
226         if (frame_label != NULL)
227                 gai->frame_label = g_strdup(frame_label);
228         else
229                 gai->frame_label = g_strdup("");
230
231         if (comment != NULL)
232                 gai->comment = g_strdup(comment);
233         else
234                 gai->comment = g_strdup("");
235         gai->conv_num=call_num;
236         gai->line_style=line_style;
237         gai->display=FALSE;
238
239         tapinfo->graph_analysis->list = g_list_append(tapinfo->graph_analysis->list, gai);
240
241 }
242
243 /****************************************************************************/
244 /* Append str to frame_label and comment in a graph item */
245 /* return 0 if the frame_num is not in the graph list */
246 static int append_to_frame_graph(voip_calls_tapinfo_t *tapinfo _U_, guint32 frame_num, const gchar *new_frame_label, const gchar *new_comment)
247 {
248         graph_analysis_item_t *gai;
249         GList *list;
250         gchar *frame_label = NULL;
251         gchar *comment = NULL;
252
253         list = g_list_first(tapinfo->graph_analysis->list);
254         while (list)
255         {
256                 gai = list->data;
257                 if (gai->frame_num == frame_num){
258                         frame_label = gai->frame_label;
259                         comment = gai->comment;
260
261                         if (new_frame_label != NULL){
262                                 gai->frame_label = g_strdup_printf("%s %s", frame_label, new_frame_label);
263                                 g_free(frame_label);
264                         }
265
266                         if (new_comment != NULL){
267                                 gai->comment = g_strdup_printf("%s %s", comment, new_comment);
268                                 g_free(comment);
269                         }
270                         break;
271                 }
272                 list = g_list_next(list);
273         }
274
275         return list ? 1 : 0;
276
277 }
278
279 /****************************************************************************/
280 /* Change the frame_label and comment in a graph item if not NULL*/
281 /* return 0 if the frame_num is not in the graph list */
282 static int change_frame_graph(voip_calls_tapinfo_t *tapinfo _U_, guint32 frame_num, const gchar *new_frame_label, const gchar *new_comment)
283 {
284         graph_analysis_item_t *gai;
285         GList *list;
286         gchar *frame_label = NULL;
287         gchar *comment = NULL;
288
289         list = g_list_first(tapinfo->graph_analysis->list);
290         while (list)
291         {
292                 gai = list->data;
293                 if (gai->frame_num == frame_num){
294                         frame_label = gai->frame_label;
295                         comment = gai->comment;
296
297                         if (new_frame_label != NULL){
298                                 gai->frame_label = g_strdup(new_frame_label);
299                                 g_free(frame_label);
300                         }
301
302                         if (new_comment != NULL){
303                                 gai->comment = g_strdup(new_comment);
304                                 g_free(comment);
305                         }
306                         break;
307                 }
308                 list = g_list_next(list);
309         }
310
311         return list ? 1 : 0;
312
313 }
314
315 /****************************************************************************/
316 /* Change all the graph items with call_num to new_call_num */
317 static guint change_call_num_graph(voip_calls_tapinfo_t *tapinfo _U_, guint16 call_num, guint16 new_call_num)
318 {
319         graph_analysis_item_t *gai;
320         GList *list;
321         guint items_changed;
322
323         items_changed = 0;
324         list = g_list_first(tapinfo->graph_analysis->list);
325         while (list)
326         {
327                 gai = list->data;
328                 if (gai->conv_num == call_num){
329                         gai->conv_num = new_call_num;
330                         items_changed++;
331                 }
332                 list = g_list_next(list);
333         }
334         return items_changed;
335 }
336
337 /****************************************************************************/
338 /* Insert the item in the graph list */
339 static void insert_to_graph(voip_calls_tapinfo_t *tapinfo _U_, packet_info *pinfo, const gchar *frame_label, const gchar *comment, guint16 call_num, address *src_addr, address *dst_addr, guint16 line_style, double time_val, guint32 frame_num)
340 {
341         graph_analysis_item_t *gai, *new_gai;
342         GList *list;
343         guint item_num;
344         gboolean inserted;
345
346         new_gai = g_malloc(sizeof(graph_analysis_item_t));
347         new_gai->frame_num = frame_num;
348         new_gai->time= time_val;
349         COPY_ADDRESS(&(new_gai->src_addr),src_addr);
350         COPY_ADDRESS(&(new_gai->dst_addr),dst_addr);
351
352         new_gai->port_src=pinfo->srcport;
353         new_gai->port_dst=pinfo->destport;
354         if (frame_label != NULL)
355                 new_gai->frame_label = g_strdup(frame_label);
356         else
357                 new_gai->frame_label = g_strdup("");
358
359         if (comment != NULL)
360                 new_gai->comment = g_strdup(comment);
361         else
362                 new_gai->comment = g_strdup("");
363         new_gai->conv_num=call_num;
364         new_gai->line_style=line_style;
365         new_gai->display=FALSE;
366
367         item_num = 0;
368         inserted = FALSE;
369         list = g_list_first(tapinfo->graph_analysis->list);
370         while (list)
371         {
372                 gai = list->data;
373                 if (gai->frame_num > frame_num){
374                         the_tapinfo_struct.graph_analysis->list = g_list_insert(the_tapinfo_struct.graph_analysis->list, new_gai, item_num);
375                         inserted = TRUE;
376                         break;
377                 }
378                 list = g_list_next(list);
379                 item_num++;
380         }
381
382         if (!inserted) tapinfo->graph_analysis->list = g_list_append(tapinfo->graph_analysis->list, new_gai);
383 }
384
385 /****************************************************************************/
386 /* ***************************TAP for RTP Events*****************************/
387 /****************************************************************************/
388
389 static guint32 rtp_evt_frame_num = 0;
390 static guint8 rtp_evt = 0;
391 static gboolean rtp_evt_end = FALSE;
392 /*static guint32 rtp_evt_setup_frame_num = 0;*/
393
394 /****************************************************************************/
395 /* whenever a rtp event packet is seen by the tap listener */
396 static int
397 rtp_event_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *rtp_event_info)
398 {
399         const struct _rtp_event_info *pi = rtp_event_info;
400
401         /* do not consider RTP events packets without a setup frame */
402         if (pi->info_setup_frame_num == 0){
403                 return 0;
404         }
405
406         rtp_evt_frame_num = pinfo->fd->num;
407         rtp_evt = pi->info_rtp_evt;
408         rtp_evt_end = pi->info_end;
409
410         return 0;
411 }
412
413 /****************************************************************************/
414 static gboolean have_rtp_event_tap_listener=FALSE;
415
416 void
417 rtp_event_init_tap(void)
418 {
419         GString *error_string;
420
421
422         if(have_rtp_event_tap_listener==FALSE)
423         {
424                 error_string = register_tap_listener("rtpevent", &(the_tapinfo_rtp_struct.rtp_event_dummy),
425                         NULL,
426                         0,
427                         NULL,
428                         rtp_event_packet,
429                         NULL
430                         );
431
432                 if (error_string != NULL) {
433                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
434                                       "%s", error_string->str);
435                         g_string_free(error_string, TRUE);
436                         exit(1);
437                 }
438                 have_rtp_event_tap_listener=TRUE;
439         }
440 }
441
442 /****************************************************************************/
443
444 void
445 remove_tap_listener_rtp_event(void)
446 {
447         protect_thread_critical_region();
448         remove_tap_listener(&(the_tapinfo_rtp_struct.rtp_event_dummy));
449         unprotect_thread_critical_region();
450
451         have_rtp_event_tap_listener=FALSE;
452 }
453
454 /****************************************************************************/
455 /* ***************************TAP for RTP **********************************/
456 /****************************************************************************/
457
458 /****************************************************************************/
459 /* when there is a [re]reading of RTP packet's */
460 static void voip_rtp_reset(void *ptr _U_)
461 {
462         voip_rtp_tapinfo_t *tapinfo = &the_tapinfo_rtp_struct;
463         GList *list;
464         /* free the data items first */
465         list = g_list_first(tapinfo->list);
466         while (list)
467         {
468                 g_free(list->data);
469                 list = g_list_next(list);
470         }
471         g_list_free(tapinfo->list);
472         tapinfo->list = NULL;
473         tapinfo->nstreams = 0;
474         return;
475 }
476
477 /****************************************************************************/
478 /* whenever a RTP packet is seen by the tap listener */
479 static int
480 RTP_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, void const *RTPinfo)
481 {
482         voip_rtp_tapinfo_t *tapinfo = &the_tapinfo_rtp_struct;
483         voip_rtp_stream_info_t *tmp_listinfo;
484         voip_rtp_stream_info_t *strinfo = NULL;
485         GList *list;
486         struct _rtp_conversation_info *p_conv_data = NULL;
487
488         const struct _rtp_info *pi = RTPinfo;
489
490         /* do not consider RTP packets without a setup frame */
491         if (pi->info_setup_frame_num == 0){
492                 return 0;
493         }
494
495         /* add this RTP for future listening using the RTP Player*/
496 #ifdef HAVE_LIBPORTAUDIO
497         add_rtp_packet(pi, pinfo);
498 #endif
499
500         /* check whether we already have a RTP stream with this setup frame and ssrc in the list */
501         list = g_list_first(tapinfo->list);
502         while (list)
503         {
504                 tmp_listinfo=list->data;
505                 if ( (tmp_listinfo->setup_frame_number == pi->info_setup_frame_num)
506                         && (tmp_listinfo->ssrc == pi->info_sync_src) && (tmp_listinfo->end_stream == FALSE)){
507                         /* if the payload type has changed, we mark the stream as finished to create a new one
508                            this is to show multiple payload changes in the Graph for example for DTMF RFC2833 */
509                         if ( tmp_listinfo->pt != pi->info_payload_type ) {
510                                 tmp_listinfo->end_stream = TRUE;
511                         } else {
512                                 strinfo = (voip_rtp_stream_info_t*)(list->data);
513                                 break;
514                         }
515                 }
516                 list = g_list_next(list);
517         }
518
519         /* if this is a duplicated RTP Event End, just return */
520         if ((rtp_evt_frame_num == pinfo->fd->num) && !strinfo && (rtp_evt_end == TRUE)) {
521                 return 0;
522         }
523
524         /* not in the list? then create a new entry */
525         if (strinfo==NULL){
526                 strinfo = g_malloc(sizeof(voip_rtp_stream_info_t));
527                 COPY_ADDRESS(&(strinfo->src_addr), &(pinfo->src));
528                 strinfo->src_port = pinfo->srcport;
529                 COPY_ADDRESS(&(strinfo->dest_addr), &(pinfo->dst));
530                 strinfo->dest_port = pinfo->destport;
531                 strinfo->ssrc = pi->info_sync_src;
532                 strinfo->end_stream = FALSE;
533                 strinfo->pt = pi->info_payload_type;
534                 strinfo->pt_str = NULL;
535                 strinfo->is_srtp = pi->info_is_srtp;
536                 /* if it is dynamic payload, let use the conv data to see if it is defined */
537                 if ( (strinfo->pt >= PT_UNDF_96) && (strinfo->pt <= PT_UNDF_127) ) {
538                         /* Use existing packet info if available */
539                         p_conv_data = p_get_proto_data(pinfo->fd, proto_get_id_by_filter_name("rtp"));
540                         if (p_conv_data && p_conv_data->rtp_dyn_payload) {
541                                 encoding_name_and_rate_t *encoding_name_and_rate_pt = NULL;
542                                 encoding_name_and_rate_pt = g_hash_table_lookup(p_conv_data->rtp_dyn_payload, &strinfo->pt);
543                                 if (encoding_name_and_rate_pt) {
544                                         strinfo->pt_str = g_strdup(encoding_name_and_rate_pt->encoding_name);
545                                 }
546                         }
547                 }
548                 if (!strinfo->pt_str) strinfo->pt_str = g_strdup(val_to_str_ext(strinfo->pt, &rtp_payload_type_short_vals_ext, "%u"));
549                 strinfo->npackets = 0;
550                 strinfo->first_frame_num = pinfo->fd->num;
551                 strinfo->start_abs = pinfo->fd->abs_ts;
552                 strinfo->start_rel = pinfo->fd->rel_ts;
553                 strinfo->setup_frame_number = pi->info_setup_frame_num;
554                 strinfo->rtp_event = -1;
555                 tapinfo->list = g_list_append(tapinfo->list, strinfo);
556         }
557
558         if (strinfo!=NULL){
559                 /* Add the info to the existing RTP stream */
560                 strinfo->npackets++;
561                 strinfo->stop_abs = pinfo->fd->abs_ts;
562                 strinfo->stop_rel = pinfo->fd->rel_ts;
563
564                 /* process RTP Event */
565                 if (rtp_evt_frame_num == pinfo->fd->num) {
566                         strinfo->rtp_event = rtp_evt;
567                         if (rtp_evt_end == TRUE) {
568                                 strinfo->end_stream = TRUE;
569                         }
570                 }
571         }
572
573         the_tapinfo_struct.redraw = TRUE;
574
575         return 1;
576 }
577
578 /****************************************************************************/
579 /* whenever a redraw in the RTP tap listener */
580 static void RTP_packet_draw(void *prs _U_)
581 {
582         voip_rtp_tapinfo_t *rtp_tapinfo = &the_tapinfo_rtp_struct;
583         GList *rtp_streams_list;
584         voip_rtp_stream_info_t *rtp_listinfo;
585         GList *voip_calls_graph_list;
586         guint item;
587         graph_analysis_item_t *gai;
588         graph_analysis_item_t *new_gai;
589         guint16 conv_num;
590         guint32 duration;
591
592         /* add each rtp stream to the graph */
593         rtp_streams_list = g_list_first(rtp_tapinfo->list);
594         while (rtp_streams_list)
595         {
596                 rtp_listinfo = rtp_streams_list->data;
597
598                 /* using the setup frame number of the RTP stream, we get the call number that it belongs */
599                 voip_calls_graph_list = g_list_first(the_tapinfo_struct.graph_analysis->list);
600                 while (voip_calls_graph_list)
601                 {
602                         gai = voip_calls_graph_list->data;
603                         conv_num = gai->conv_num;
604                         /* if we get the setup frame number, then get the time position to graph the RTP arrow */
605                         if (rtp_listinfo->setup_frame_number == gai->frame_num){
606                                 /* look again from the begining because there are cases where the Setup frame is after the RTP */
607                                 voip_calls_graph_list = g_list_first(the_tapinfo_struct.graph_analysis->list);
608                                 item = 0;
609                                 while(voip_calls_graph_list){
610                                         gai = voip_calls_graph_list->data;
611                                         /* if RTP was already in the Graph, just update the comment information */
612                                         if (rtp_listinfo->first_frame_num == gai->frame_num){
613                                                 duration = (guint32)(nstime_to_msec(&rtp_listinfo->stop_rel) - nstime_to_msec(&rtp_listinfo->start_rel));
614                                                 g_free(gai->comment);
615                                                 gai->comment = g_strdup_printf("%s Num packets:%u  Duration:%u.%03us SSRC:0x%X",
616                                                                                                                 (rtp_listinfo->is_srtp)?"SRTP":"RTP", rtp_listinfo->npackets,
617                                                                                                                 duration/1000,(duration%1000), rtp_listinfo->ssrc);
618                                                 break;
619                                         }
620
621                                         /* 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 */
622                                         voip_calls_graph_list = g_list_next(voip_calls_graph_list);
623                                         if (!voip_calls_graph_list) item++;
624
625                                         /* add the RTP item to the graph if was not there*/
626                                         if (rtp_listinfo->first_frame_num<gai->frame_num || !voip_calls_graph_list){
627                                                 new_gai = g_malloc(sizeof(graph_analysis_item_t));
628                                                 new_gai->frame_num = rtp_listinfo->first_frame_num;
629                                                 new_gai->time = nstime_to_sec(&rtp_listinfo->start_rel);
630                                                 COPY_ADDRESS(&(new_gai->src_addr),&(rtp_listinfo->src_addr));
631                                                 COPY_ADDRESS(&(new_gai->dst_addr),&(rtp_listinfo->dest_addr));
632                                                 new_gai->port_src = rtp_listinfo->src_port;
633                                                 new_gai->port_dst = rtp_listinfo->dest_port;
634                                                 duration = (guint32)(nstime_to_msec(&rtp_listinfo->stop_rel) - nstime_to_msec(&rtp_listinfo->start_rel));
635                                                 new_gai->frame_label = g_strdup_printf("%s (%s) %s",
636                                                                                        (rtp_listinfo->is_srtp)?"SRTP":"RTP",
637                                                                                        rtp_listinfo->pt_str,
638                                                                                        (rtp_listinfo->rtp_event == -1)?
639                                                                                          "":val_to_str_const(rtp_listinfo->rtp_event, rtp_event_type_values, "Unknown RTP Event"));
640                                                 new_gai->comment = g_strdup_printf("%s Num packets:%u  Duration:%u.%03us SSRC:0x%X",
641                                                                                                                         (rtp_listinfo->is_srtp)?"SRTP":"RTP", rtp_listinfo->npackets,
642                                                                                                                         duration/1000,(duration%1000), rtp_listinfo->ssrc);
643                                                 new_gai->conv_num = conv_num;
644                                                 new_gai->display=FALSE;
645                                                 new_gai->line_style = 2;  /* the arrow line will be 2 pixels width */
646                                                 the_tapinfo_struct.graph_analysis->list = g_list_insert(the_tapinfo_struct.graph_analysis->list, new_gai, item);
647                                                 break;
648                                         }
649                                         if (voip_calls_graph_list) item++;
650                                 }
651                                 break;
652                         }
653                         voip_calls_graph_list = g_list_next(voip_calls_graph_list);
654                 }
655                 rtp_streams_list = g_list_next(rtp_streams_list);
656         }
657 }
658
659 static gboolean have_RTP_tap_listener=FALSE;
660 /****************************************************************************/
661 void
662 rtp_init_tap(void)
663 {
664         GString *error_string;
665
666         if(have_RTP_tap_listener==FALSE)
667         {
668                 /* don't register tap listener, if we have it already */
669                 error_string = register_tap_listener("rtp", &(the_tapinfo_rtp_struct.rtp_dummy), NULL,
670                         0,
671                         voip_rtp_reset,
672                         RTP_packet,
673                         RTP_packet_draw
674                         );
675                 if (error_string != NULL) {
676                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
677                                       "%s", error_string->str);
678                         g_string_free(error_string, TRUE);
679                         exit(1);
680                 }
681                 have_RTP_tap_listener=TRUE;
682         }
683 }
684
685 /****************************************************************************/
686 void
687 remove_tap_listener_rtp(void)
688 {
689         protect_thread_critical_region();
690         remove_tap_listener(&(the_tapinfo_rtp_struct.rtp_dummy));
691         unprotect_thread_critical_region();
692
693         have_RTP_tap_listener=FALSE;
694 }
695
696 /****************************************************************************/
697 /******************************TAP for T38 **********************************/
698 /****************************************************************************/
699
700 /****************************************************************************/
701 /* whenever a T38 packet is seen by the tap listener */
702 static int
703 T38_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *T38info)
704 {
705         voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
706
707         voip_calls_info_t *callsinfo = NULL;
708         voip_calls_info_t *tmp_listinfo;
709         GList *voip_calls_graph_list;
710         GList *list;
711         gchar *frame_label = NULL;
712         gchar *comment = NULL;
713         graph_analysis_item_t *tmp_gai, *gai = NULL;
714         guint16 line_style = 2;
715         double duration;
716         int conv_num = -1;
717
718         const t38_packet_info *pi = T38info;
719
720         if  (pi->setup_frame_number != 0) {
721                 /* using the setup frame number of the T38 packet, we get the call number that it belongs */
722                 voip_calls_graph_list = g_list_first(tapinfo->graph_analysis->list);
723                 while (voip_calls_graph_list)
724                 {
725                         tmp_gai = voip_calls_graph_list->data;
726                         if (pi->setup_frame_number == tmp_gai->frame_num){
727                                 gai = tmp_gai;
728                                 break;
729                         }
730                         voip_calls_graph_list = g_list_next(voip_calls_graph_list);
731                 }
732                 if (gai) conv_num = (int) gai->conv_num;
733         }
734
735         /* 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
736          * have the associated Voip calls. It probably means the the packet was decoded using the default t38 port, or using "Decode as.."
737          * in this case we create a "voip" call that only have t38 media (no signaling)
738          * OR if we have not found the Setup message in the graph.
739          */
740         if ( (pi->setup_frame_number == 0) || (gai == NULL) ){
741                 /* check whether we already have a call with these parameters in the list */
742                 list = g_list_first(tapinfo->callsinfo_list);
743                 while (list)
744                 {
745                         tmp_listinfo=list->data;
746                         if (tmp_listinfo->protocol == MEDIA_T38){
747                                 callsinfo = (voip_calls_info_t*)(list->data);
748                                 break;
749                         }
750                         list = g_list_next (list);
751                 }
752
753                 /* not in the list? then create a new entry */
754                 if (callsinfo==NULL){
755                         callsinfo = g_malloc0(sizeof(voip_calls_info_t));
756                         callsinfo->call_active_state = VOIP_ACTIVE;
757                         callsinfo->call_state = VOIP_UNKNOWN;
758                         callsinfo->from_identity=g_strdup("T38 Media only");
759                         callsinfo->to_identity=g_strdup("T38 Media only");
760                         COPY_ADDRESS(&(callsinfo->initial_speaker),&(pinfo->src));
761                         callsinfo->first_frame_num=pinfo->fd->num;
762                         callsinfo->selected=FALSE;
763                         callsinfo->start_abs = pinfo->fd->abs_ts;
764                         callsinfo->start_rel = pinfo->fd->rel_ts;
765                         callsinfo->protocol=MEDIA_T38;
766                         callsinfo->prot_info=NULL;
767                         callsinfo->free_prot_info = NULL;
768                         callsinfo->npackets = 0;
769                         callsinfo->call_num = tapinfo->ncalls++;
770                         tapinfo->callsinfo_list = g_list_append(tapinfo->callsinfo_list, callsinfo);
771                 }
772                 ++(callsinfo->npackets);
773                 /* increment the packets counter of all calls */
774                 ++(tapinfo->npackets);
775
776                 conv_num = (int) callsinfo->call_num;
777         }
778
779         /* at this point we should have found the call num for this t38 packets belong */
780         if (conv_num == -1) {
781                 return 0;
782         }
783
784         /* add the item to the graph list */
785         if (pi->type_msg == 0) { /* 0=t30-indicator */
786                 frame_label = g_strdup(val_to_str(pi->t30ind_value, t38_T30_indicator_vals, "Ukn (0x%02X)") );
787                 comment = g_strdup_printf("t38:t30 Ind:%s",val_to_str(pi->t30ind_value, t38_T30_indicator_vals, "Ukn (0x%02X)") );
788                 line_style = 1;
789         } else if (pi->type_msg == 1) { /* 1=data */
790                 switch(pi->Data_Field_field_type_value){
791                         case 0: /* hdlc-data */
792                                 break;
793                         case 2: /* hdlc-fcs-OK */
794                         case 4: /* hdlc-fcs-OK-sig-end */
795                                 frame_label = g_strdup_printf("%s %s", val_to_str(pi->t30_Facsimile_Control & 0x7F, t30_facsimile_control_field_vals_short, "Ukn (0x%02X)"), pi->desc);
796                                 comment = g_strdup_printf("t38:%s:HDLC:%s",val_to_str(pi->data_value, t38_T30_data_vals, "Ukn (0x%02X)"), val_to_str(pi->t30_Facsimile_Control & 0x7F, t30_facsimile_control_field_vals, "Ukn (0x%02X)"));
797                                 break;
798                         case 3: /* hdlc-fcs-BAD */
799                         case 5: /* hdlc-fcs-BAD-sig-end */
800                                 frame_label = g_strdup(pi->Data_Field_field_type_value == 3 ? "fcs-BAD" : "fcs-BAD-sig-end");
801                                 comment = g_strdup_printf("WARNING: received t38:%s:HDLC:%s", val_to_str(pi->data_value, t38_T30_data_vals, "Ukn (0x%02X)"), pi->Data_Field_field_type_value == 3 ? "fcs-BAD" : "fcs-BAD-sig-end");
802                                 break;
803                         case 7: /* t4-non-ecm-sig-end */
804                                 duration = nstime_to_sec(&pinfo->fd->rel_ts) - pi->time_first_t4_data;
805                                 frame_label = g_strdup_printf("t4-non-ecm-data:%s",val_to_str(pi->data_value, t38_T30_data_vals, "Ukn (0x%02X)") );
806                                 comment = g_strdup_printf("t38:t4-non-ecm-data:%s Duration: %.2fs %s",val_to_str(pi->data_value, t38_T30_data_vals, "Ukn (0x%02X)"), duration, pi->desc_comment );
807                                 insert_to_graph(tapinfo, pinfo, frame_label, comment, (guint16)conv_num, &(pinfo->src), &(pinfo->dst), line_style, pi->time_first_t4_data, pi->frame_num_first_t4_data);
808                                 break;
809                 }
810         }
811
812         if (frame_label && !(pi->Data_Field_field_type_value == 7 && pi->type_msg == 1)) {
813                 add_to_graph(tapinfo, pinfo, frame_label, comment, (guint16)conv_num, &(pinfo->src), &(pinfo->dst), line_style);
814         }
815
816         g_free(comment);
817         g_free(frame_label);
818
819         tapinfo->redraw = TRUE;
820
821         return 1;  /* refresh output */
822 }
823
824 static gboolean have_T38_tap_listener=FALSE;
825 /****************************************************************************/
826 void
827 t38_init_tap(void)
828 {
829         GString *error_string;
830
831         if(have_T38_tap_listener==FALSE)
832         {
833                 /* don't register tap listener, if we have it already */
834                 error_string = register_tap_listener("t38", &(the_tapinfo_struct.t38_dummy), NULL,
835                         0,
836                         voip_calls_dlg_reset,
837                         T38_packet,
838                         voip_calls_dlg_draw
839                         );
840                 if (error_string != NULL) {
841                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
842                                       "%s", error_string->str);
843                         g_string_free(error_string, TRUE);
844                         exit(1);
845                 }
846                 have_T38_tap_listener=TRUE;
847         }
848 }
849
850 /****************************************************************************/
851 void
852 remove_tap_listener_t38(void)
853 {
854         protect_thread_critical_region();
855         remove_tap_listener(&(the_tapinfo_struct.t38_dummy));
856         unprotect_thread_critical_region();
857
858         have_T38_tap_listener=FALSE;
859 }
860
861
862 /****************************************************************************/
863 static gchar *sdp_summary = NULL;
864 static guint32 sdp_frame_num = 0;
865
866 /****************************************************************************/
867 /* ***************************TAP for SIP **********************************/
868 /****************************************************************************/
869
870
871 static void free_sip_info(gpointer p) {
872         sip_calls_info_t *si = p;
873
874         g_free(si->call_identifier);
875         g_free(si);
876 }
877
878 /****************************************************************************/
879 /* whenever a SIP packet is seen by the tap listener */
880 static int
881 SIPcalls_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *SIPinfo)
882 {
883         voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
884         /* we just take note of the ISUP data here; when we receive the MTP3 part everything will
885            be compared with existing calls */
886
887         voip_calls_info_t *tmp_listinfo;
888         voip_calls_info_t *callsinfo = NULL;
889         sip_calls_info_t *tmp_sipinfo = NULL;
890         GList *list;
891         address tmp_src, tmp_dst;
892         gchar *frame_label = NULL;
893         gchar *comment = NULL;
894
895         const sip_info_value_t *pi = SIPinfo;
896
897         /* do not consider packets without call_id */
898         if (pi->tap_call_id ==NULL){
899                 return 0;
900         }
901
902         /* check whether we already have a call with these parameters in the list */
903         list = g_list_first(tapinfo->callsinfo_list);
904         while (list)
905         {
906                 tmp_listinfo=list->data;
907                 if (tmp_listinfo->protocol == VOIP_SIP){
908                         tmp_sipinfo = tmp_listinfo->prot_info;
909                         if (strcmp(tmp_sipinfo->call_identifier,pi->tap_call_id)==0){
910                                 callsinfo = (voip_calls_info_t*)(list->data);
911                                 break;
912                         }
913                 }
914                 list = g_list_next (list);
915         }
916
917         /* not in the list? then create a new entry if the message is INVITE -i.e. if this session is a call*/
918         if ((callsinfo==NULL) &&(pi->request_method!=NULL)){
919                 if (strcmp(pi->request_method,"INVITE")==0){
920                         callsinfo = g_malloc0(sizeof(voip_calls_info_t));
921                         callsinfo->call_active_state = VOIP_ACTIVE;
922                         callsinfo->call_state = VOIP_CALL_SETUP;
923                         callsinfo->from_identity=g_strdup(pi->tap_from_addr);
924                         callsinfo->to_identity=g_strdup(pi->tap_to_addr);
925                         COPY_ADDRESS(&(callsinfo->initial_speaker),&(pinfo->src));
926                         callsinfo->first_frame_num=pinfo->fd->num;
927                         callsinfo->selected=FALSE;
928                         callsinfo->start_abs=pinfo->fd->abs_ts;
929                         callsinfo->start_rel=pinfo->fd->rel_ts;
930                         callsinfo->protocol=VOIP_SIP;
931                         callsinfo->prot_info=g_malloc(sizeof(sip_calls_info_t));
932                         callsinfo->free_prot_info = free_sip_info;
933                         tmp_sipinfo = callsinfo->prot_info;
934                         tmp_sipinfo->call_identifier = g_strdup(pi->tap_call_id);
935                         tmp_sipinfo->sip_state = SIP_INVITE_SENT;
936                         tmp_sipinfo->invite_cseq = pi->tap_cseq_number;
937                         callsinfo->npackets = 0;
938                         callsinfo->call_num = tapinfo->ncalls++;
939                         tapinfo->callsinfo_list = g_list_append(tapinfo->callsinfo_list, callsinfo);
940                 }
941         }
942
943         if (callsinfo!=NULL){
944
945                 /* let's analyze the call state */
946
947                 COPY_ADDRESS(&(tmp_src), &(pinfo->src));
948                 COPY_ADDRESS(&(tmp_dst), &(pinfo->dst));
949
950                 if (pi->request_method == NULL){
951                         frame_label = g_strdup_printf("%u %s", pi->response_code, pi->reason_phrase );
952                         comment = g_strdup("SIP Status");
953
954                         if ((tmp_sipinfo && pi->tap_cseq_number == tmp_sipinfo->invite_cseq)&&(ADDRESSES_EQUAL(&tmp_dst,&(callsinfo->initial_speaker)))){
955                                 if ((pi->response_code > 199) && (pi->response_code<300) && (tmp_sipinfo->sip_state == SIP_INVITE_SENT)){
956                                         tmp_sipinfo->sip_state = SIP_200_REC;
957                                 }
958                                 else if ((pi->response_code>299)&&(tmp_sipinfo->sip_state == SIP_INVITE_SENT)){
959                                         callsinfo->call_state = VOIP_REJECTED;
960                                         tapinfo->rejected_calls++;
961                                 }
962                         }
963
964                 }
965                 else{
966                         frame_label = g_strdup(pi->request_method);
967
968                         if ((strcmp(pi->request_method,"INVITE")==0)&&(ADDRESSES_EQUAL(&tmp_src,&(callsinfo->initial_speaker)))){
969                                 tmp_sipinfo->invite_cseq = pi->tap_cseq_number;
970                                 callsinfo->call_state = VOIP_CALL_SETUP;
971                                 comment = g_strdup_printf("SIP From: %s To:%s", callsinfo->from_identity, callsinfo->to_identity);
972                         }
973                         else if ((strcmp(pi->request_method,"ACK")==0)&&(pi->tap_cseq_number == tmp_sipinfo->invite_cseq)
974                                 &&(ADDRESSES_EQUAL(&tmp_src,&(callsinfo->initial_speaker)))&&(tmp_sipinfo->sip_state==SIP_200_REC)
975                                 &&(callsinfo->call_state == VOIP_CALL_SETUP)){
976                                 callsinfo->call_state = VOIP_IN_CALL;
977                                 comment = g_strdup("SIP Request");
978                         }
979                         else if (strcmp(pi->request_method,"BYE")==0){
980                                 callsinfo->call_state = VOIP_COMPLETED;
981                                 tapinfo->completed_calls++;
982                                 comment = g_strdup("SIP Request");
983                         }
984                         else if ((strcmp(pi->request_method,"CANCEL")==0)&&(pi->tap_cseq_number == tmp_sipinfo->invite_cseq)
985                                 &&(ADDRESSES_EQUAL(&tmp_src,&(callsinfo->initial_speaker)))&&(callsinfo->call_state==VOIP_CALL_SETUP)){
986                                 callsinfo->call_state = VOIP_CANCELLED;
987                                 tmp_sipinfo->sip_state = SIP_CANCEL_SENT;
988                                 comment = g_strdup("SIP Request");
989                         } else {
990                                 comment = g_strdup("SIP Request");
991                         }
992                 }
993
994                 callsinfo->stop_abs = pinfo->fd->abs_ts;
995                 callsinfo->stop_rel = pinfo->fd->rel_ts;
996                 callsinfo->last_frame_num=pinfo->fd->num;
997                 ++(callsinfo->npackets);
998                 /* increment the packets counter of all calls */
999                 ++(tapinfo->npackets);
1000
1001                 /* add to the graph */
1002                 add_to_graph(tapinfo, pinfo, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
1003                 g_free(comment);
1004                 g_free(frame_label);
1005                 g_free((void *)tmp_src.data);
1006                 g_free((void *)tmp_dst.data);
1007
1008                 /* add SDP info if apply */
1009                 if ( (sdp_summary != NULL) && (sdp_frame_num == pinfo->fd->num) ){
1010                                 append_to_frame_graph(tapinfo, pinfo->fd->num, sdp_summary, NULL);
1011                                 g_free(sdp_summary);
1012                                 sdp_summary = NULL;
1013                 }
1014         }
1015
1016         tapinfo->redraw = TRUE;
1017
1018         return 1;  /* refresh output */
1019 }
1020
1021
1022 /****************************************************************************/
1023 voip_calls_tapinfo_t* voip_calls_get_info(void)
1024 {
1025         return &the_tapinfo_struct;
1026 }
1027
1028
1029 /****************************************************************************/
1030 /* TAP INTERFACE */
1031 /****************************************************************************/
1032 static gboolean have_SIP_tap_listener=FALSE;
1033 /****************************************************************************/
1034 void
1035 sip_calls_init_tap(void)
1036 {
1037         GString *error_string;
1038
1039         if(have_SIP_tap_listener==FALSE)
1040         {
1041                 /* don't register tap listener, if we have it already */
1042                 error_string = register_tap_listener("sip", &(the_tapinfo_struct.sip_dummy), NULL,
1043                         0,
1044                         voip_calls_dlg_reset,
1045                         SIPcalls_packet,
1046                         voip_calls_dlg_draw
1047                         );
1048                 if (error_string != NULL) {
1049                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1050                                       "%s", error_string->str);
1051                         g_string_free(error_string, TRUE);
1052                         exit(1);
1053                 }
1054                 have_SIP_tap_listener=TRUE;
1055         }
1056 }
1057
1058 /****************************************************************************/
1059 void
1060 remove_tap_listener_sip_calls(void)
1061 {
1062         protect_thread_critical_region();
1063         remove_tap_listener(&(the_tapinfo_struct.sip_dummy));
1064         unprotect_thread_critical_region();
1065
1066         have_SIP_tap_listener=FALSE;
1067 }
1068
1069 /****************************************************************************/
1070 /* ***************************TAP for ISUP **********************************/
1071 /****************************************************************************/
1072
1073 static  guint32         mtp3_opc, mtp3_dpc;
1074 static  guint8          mtp3_ni;
1075 static  guint32         mtp3_frame_num;
1076
1077
1078 /****************************************************************************/
1079 /* whenever a isup_ packet is seen by the tap listener */
1080 static int
1081 isup_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *isup_info _U_)
1082 {
1083         voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
1084         voip_calls_info_t *tmp_listinfo;
1085         voip_calls_info_t *callsinfo = NULL;
1086         isup_calls_info_t *tmp_isupinfo;
1087         gboolean found = FALSE;
1088         gboolean forward = FALSE;
1089         gboolean right_pair;
1090         GList *list;
1091         gchar *frame_label = NULL;
1092         gchar *comment = NULL;
1093
1094         /*voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct; unused */
1095         const isup_tap_rec_t *pi = isup_info;
1096
1097         /* check if the lower layer is MTP matching the frame number */
1098         if (mtp3_frame_num != pinfo->fd->num) return 0;
1099
1100         /* check whether we already have a call with these parameters in the list */
1101         list = g_list_first(tapinfo->callsinfo_list);
1102         while (list)
1103         {
1104                 right_pair = TRUE;
1105                 tmp_listinfo=list->data;
1106                 if ((tmp_listinfo->protocol == VOIP_ISUP)&&(tmp_listinfo->call_active_state==VOIP_ACTIVE)){
1107                         tmp_isupinfo = tmp_listinfo->prot_info;
1108                         if ((tmp_isupinfo->cic == pinfo->circuit_id)&&(tmp_isupinfo->ni == mtp3_ni)) {
1109                                 if ((tmp_isupinfo->opc == mtp3_opc)&&(tmp_isupinfo->dpc == mtp3_dpc)){
1110                                          forward = TRUE;
1111                                 } else if ((tmp_isupinfo->dpc == mtp3_opc)&&(tmp_isupinfo->opc == mtp3_dpc)){
1112                                          forward = FALSE;
1113                                 } else{
1114                                         right_pair = FALSE;
1115                                 }
1116
1117                                  if (right_pair){
1118                                         /* if there is an IAM for a call that is not in setup state, that means the previous call in the same
1119                                            cic is no longer active */
1120                                         if (tmp_listinfo->call_state == VOIP_CALL_SETUP){
1121                                                 found = TRUE;
1122                                         } else if (pi->message_type != 1){
1123                                                 found = TRUE;
1124                                         } else{
1125                                                 tmp_listinfo->call_active_state=VOIP_INACTIVE;
1126                                         }
1127                                 }
1128
1129                                 if (found){
1130                                         callsinfo = (voip_calls_info_t*)(list->data);
1131                                         break;
1132                                 }
1133                         }
1134                 }
1135                 list = g_list_next (list);
1136         }
1137
1138         /* not in the list? then create a new entry if the message is IAM
1139            -i.e. if this session is a call*/
1140
1141
1142         if ((callsinfo==NULL) &&(pi->message_type==1)){
1143                 callsinfo = g_malloc0(sizeof(voip_calls_info_t));
1144                 callsinfo->call_active_state = VOIP_ACTIVE;
1145                 callsinfo->call_state = VOIP_UNKNOWN;
1146                 COPY_ADDRESS(&(callsinfo->initial_speaker),&(pinfo->src));
1147                 callsinfo->selected=FALSE;
1148                 callsinfo->first_frame_num=pinfo->fd->num;
1149                 callsinfo->start_abs=pinfo->fd->abs_ts;
1150                 callsinfo->start_rel=pinfo->fd->rel_ts;
1151                 callsinfo->protocol=VOIP_ISUP;
1152                 if (pi->calling_number!=NULL){
1153                         callsinfo->from_identity=g_strdup(pi->calling_number);
1154                 }
1155                 if (pi->called_number!=NULL){
1156                         callsinfo->to_identity=g_strdup(pi->called_number);
1157                 }
1158                 callsinfo->prot_info=g_malloc(sizeof(isup_calls_info_t));
1159                 callsinfo->free_prot_info = g_free;
1160                 tmp_isupinfo=callsinfo->prot_info;
1161                 tmp_isupinfo->opc = mtp3_opc;
1162                 tmp_isupinfo->dpc = mtp3_dpc;
1163                 tmp_isupinfo->ni = mtp3_ni;
1164                 tmp_isupinfo->cic = pinfo->circuit_id;
1165                 callsinfo->npackets = 0;
1166                 callsinfo->call_num = tapinfo->ncalls++;
1167                 tapinfo->callsinfo_list = g_list_append(tapinfo->callsinfo_list, callsinfo);
1168         }
1169
1170
1171         if (callsinfo!=NULL){
1172                 callsinfo->stop_abs = pinfo->fd->abs_ts;
1173                 callsinfo->stop_rel = pinfo->fd->rel_ts;
1174                 callsinfo->last_frame_num=pinfo->fd->num;
1175                 ++(callsinfo->npackets);
1176
1177                 /* Let's analyze the call state */
1178
1179                 frame_label = g_strdup(val_to_str_ext_const(pi->message_type, &isup_message_type_value_acro_ext, "Unknown"));
1180
1181                 if (callsinfo->npackets == 1){ /* this is the first packet, that must be an IAM */
1182
1183                         if ((pi->calling_number!=NULL)&&(pi->called_number !=NULL)){
1184                                 comment = g_strdup_printf("Call from %s to %s",
1185                                  pi->calling_number, pi->called_number);
1186                          }
1187                 } else if (callsinfo->npackets == 2){ /* in the second packet we show the SPs */
1188                         if (forward){
1189                                 comment = g_strdup_printf("%i-%i -> %i-%i. Cic:%i",
1190                                  mtp3_ni, mtp3_opc,
1191                                  mtp3_ni, mtp3_dpc, pinfo->circuit_id);
1192                         } else {
1193                                 comment = g_strdup_printf("%i-%i -> %i-%i. Cic:%i",
1194                                  mtp3_ni, mtp3_dpc,
1195                                  mtp3_ni, mtp3_opc, pinfo->circuit_id);
1196                         }
1197                 }
1198
1199
1200                 switch(pi->message_type){
1201                         case 1: /* IAM */
1202                                 callsinfo->call_state=VOIP_CALL_SETUP;
1203                                 break;
1204                         case 7: /* CONNECT */
1205                         case 9: /* ANSWER */
1206                                 callsinfo->call_state=VOIP_IN_CALL;
1207                                 break;
1208                         case 12: /* RELEASE */
1209                                 if (callsinfo->call_state==VOIP_CALL_SETUP){
1210                                         if (forward){
1211                                                 callsinfo->call_state=VOIP_CANCELLED;
1212                                         }
1213                                         else{
1214                                                 callsinfo->call_state=VOIP_REJECTED;
1215                                                 tapinfo->rejected_calls++;
1216                                         }
1217                                 }
1218                                 else if (callsinfo->call_state == VOIP_IN_CALL){
1219                                         callsinfo->call_state = VOIP_COMPLETED;
1220                                         tapinfo->completed_calls++;
1221                                 }
1222                                 comment = g_strdup_printf("Cause %i - %s",
1223                                                           pi->cause_value,
1224                                                           val_to_str_ext_const(pi->cause_value, &q931_cause_code_vals_ext, "(Unknown)"));
1225                                 break;
1226                 }
1227
1228                 /* increment the packets counter of all calls */
1229                 ++(tapinfo->npackets);
1230
1231                 /* add to the graph */
1232                 add_to_graph(tapinfo, pinfo, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
1233                 g_free(comment);
1234                 g_free(frame_label);
1235         }
1236
1237         tapinfo->redraw = TRUE;
1238
1239         return 1;  /* refresh output */
1240 }
1241
1242 /****************************************************************************/
1243
1244 static gboolean have_isup_tap_listener=FALSE;
1245
1246 void
1247 isup_calls_init_tap(void)
1248 {
1249         GString *error_string;
1250
1251
1252         if(have_isup_tap_listener==FALSE)
1253         {
1254                 error_string = register_tap_listener("isup", &(the_tapinfo_struct.isup_dummy),
1255                         NULL,
1256                         0,
1257                         voip_calls_dlg_reset,
1258                         isup_calls_packet,
1259                         voip_calls_dlg_draw
1260                         );
1261
1262                 if (error_string != NULL) {
1263                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1264                                       "%s", error_string->str);
1265                         g_string_free(error_string, TRUE);
1266                         exit(1);
1267                 }
1268                 have_isup_tap_listener=TRUE;
1269         }
1270 }
1271
1272 /****************************************************************************/
1273
1274 void
1275 remove_tap_listener_isup_calls(void)
1276 {
1277         protect_thread_critical_region();
1278         remove_tap_listener(&(the_tapinfo_struct.isup_dummy));
1279         unprotect_thread_critical_region();
1280
1281         have_isup_tap_listener=FALSE;
1282 }
1283
1284
1285 /****************************************************************************/
1286 /* ***************************TAP for MTP3 **********************************/
1287 /****************************************************************************/
1288
1289
1290 /****************************************************************************/
1291 /* whenever a mtp3_ packet is seen by the tap listener */
1292 static int
1293 mtp3_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *mtp3_info _U_)
1294 {
1295         const mtp3_tap_rec_t *pi = mtp3_info;
1296
1297         /* keep the data in memory to use when the ISUP information arrives */
1298
1299         mtp3_opc = pi->addr_opc.pc;
1300         mtp3_dpc = pi->addr_dpc.pc;
1301         mtp3_ni = pi->addr_opc.ni;
1302         mtp3_frame_num = pinfo->fd->num;
1303
1304         return 0;
1305 }
1306
1307 /****************************************************************************/
1308
1309 static gboolean have_mtp3_tap_listener=FALSE;
1310 static gboolean have_m3ua_tap_listener=FALSE;
1311
1312 void
1313 mtp3_calls_init_tap(void)
1314 {
1315         GString *error_string;
1316
1317
1318         if(have_mtp3_tap_listener==FALSE)
1319         {
1320                 error_string = register_tap_listener("mtp3", &(the_tapinfo_struct.mtp3_dummy),
1321                         NULL,
1322                         0,
1323                         voip_calls_dlg_reset,
1324                         mtp3_calls_packet,
1325                         voip_calls_dlg_draw
1326                         );
1327
1328                 if (error_string != NULL) {
1329                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1330                                       "%s", error_string->str);
1331                         g_string_free(error_string, TRUE);
1332                         exit(1);
1333                 }
1334                 have_mtp3_tap_listener=TRUE;
1335         }
1336
1337         if(have_m3ua_tap_listener==FALSE)
1338         {
1339                 error_string = register_tap_listener("m3ua", &(the_tapinfo_struct.mtp3_dummy),
1340                         NULL,
1341                         0,
1342                         voip_calls_dlg_reset,
1343                         mtp3_calls_packet,
1344                         voip_calls_dlg_draw
1345                         );
1346
1347                 if (error_string != NULL) {
1348                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1349                                       "%s", error_string->str);
1350                         g_string_free(error_string, TRUE);
1351                         exit(1);
1352                 }
1353                 have_m3ua_tap_listener=TRUE;
1354         }
1355
1356 }
1357
1358 /****************************************************************************/
1359
1360 void
1361 remove_tap_listener_mtp3_calls(void)
1362 {
1363         protect_thread_critical_region();
1364         remove_tap_listener(&(the_tapinfo_struct.mtp3_dummy));
1365         remove_tap_listener(&(the_tapinfo_struct.m3ua_dummy));
1366         unprotect_thread_critical_region();
1367
1368         have_mtp3_tap_listener=FALSE;
1369         have_m3ua_tap_listener=FALSE;
1370 }
1371
1372 /****************************************************************************/
1373 /* ***************************TAP for Q931 **********************************/
1374 /****************************************************************************/
1375 void h245_add_to_graph(guint32 new_frame_num);
1376 static const e_guid_t guid_allzero = {0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } };
1377 /* defines specific H323 data */
1378
1379 static gchar *q931_calling_number;
1380 static gchar *q931_called_number;
1381 static guint8 q931_cause_value;
1382 static gint32 q931_crv;
1383 static guint32 q931_frame_num;
1384
1385 static guint32 h225_frame_num = 0;
1386 static guint16 h225_call_num = 0;
1387 static h225_cs_type h225_cstype = H225_OTHER;
1388 static gboolean h225_is_faststart;
1389
1390 static guint32 actrace_frame_num = 0;
1391 static gint32 actrace_trunk = 0;
1392 static gint32 actrace_direction = 0;
1393
1394
1395 /****************************************************************************/
1396 /* whenever a q931_ packet is seen by the tap listener */
1397 static int
1398 q931_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *q931_info)
1399 {
1400         GList *list,*list2;
1401         voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
1402         h323_calls_info_t *tmp_h323info,*tmp2_h323info;
1403         actrace_isdn_calls_info_t *tmp_actrace_isdn_info;
1404         voip_calls_info_t *tmp_listinfo;
1405         voip_calls_info_t *callsinfo = NULL;
1406         h245_address_t *h245_add = NULL;
1407         gchar *comment;
1408
1409         const q931_packet_info *pi = q931_info;
1410
1411         /* free previously allocated q931_calling/ed_number */
1412         g_free(q931_calling_number);
1413         g_free(q931_called_number);
1414
1415         if (pi->calling_number!=NULL)
1416                 q931_calling_number = g_strdup(pi->calling_number);
1417         else
1418                 q931_calling_number = g_strdup("");
1419
1420         if (pi->called_number!=NULL)
1421                 q931_called_number = g_strdup(pi->called_number);
1422         else
1423                 q931_called_number = g_strdup("");
1424         q931_cause_value = pi->cause_value;
1425         q931_frame_num = pinfo->fd->num;
1426         q931_crv = pi->crv;
1427
1428
1429         /* add staff to H323 calls */
1430         if (h225_frame_num == q931_frame_num) {
1431                 tmp_h323info = NULL;
1432                 list = g_list_first(tapinfo->callsinfo_list);
1433                 while (list)
1434                 {
1435                         tmp_listinfo=list->data;
1436                         if ( (tmp_listinfo->protocol == VOIP_H323) && (tmp_listinfo->call_num == h225_call_num) ){
1437                                 tmp_h323info = tmp_listinfo->prot_info;
1438                                 callsinfo = (voip_calls_info_t*)(list->data);
1439
1440                                 /* Add the CRV to the h323 call */
1441                                 if (tmp_h323info->q931_crv == -1) {
1442                                         tmp_h323info->q931_crv = q931_crv;
1443                                 } else if (tmp_h323info->q931_crv != q931_crv) {
1444                                         tmp_h323info->q931_crv2 = q931_crv;
1445                                 }
1446                                 break;
1447                         }
1448                         list = g_list_next (list);
1449                 }
1450
1451                 if (callsinfo != NULL) {
1452                         comment = NULL;
1453                         if (h225_cstype == H225_SETUP) {
1454                                 /* set te calling and called number from the Q931 packet */
1455                                 if (q931_calling_number != NULL){
1456                                         g_free(callsinfo->from_identity);
1457                                         callsinfo->from_identity=g_strdup(q931_calling_number);
1458                                 }
1459                                 if (q931_called_number != NULL){
1460                                         g_free(callsinfo->to_identity);
1461                                         callsinfo->to_identity=g_strdup(q931_called_number);
1462                                 }
1463
1464                                 /* check if there is an LRQ/LCF that match this Setup */
1465                                 /* TODO: we are just checking the DialedNumer in LRQ/LCF agains the Setup
1466                                         we should also check if the h225 signaling IP and port match the destination
1467                                         Setup ip and port */
1468                                 list = g_list_first(tapinfo->callsinfo_list);
1469                                 while (list)
1470                                 {
1471                                         tmp_listinfo=list->data;
1472                                         if (tmp_listinfo->protocol == VOIP_H323){
1473                                                 tmp2_h323info = tmp_listinfo->prot_info;
1474
1475                                                 /* check if the called number match a LRQ/LCF */
1476                                                 if ( (strcmp(callsinfo->to_identity, tmp_listinfo->to_identity)==0)
1477                                                          && (memcmp(&tmp2_h323info->guid, &guid_allzero, GUID_LEN) == 0) ){
1478                                                         /* change the call graph to the LRQ/LCF to belong to this call */
1479                                                         callsinfo->npackets += change_call_num_graph(tapinfo, tmp_listinfo->call_num, callsinfo->call_num);
1480
1481                                                         /* remove this LRQ/LCF call entry because we have found the Setup that match them */
1482                                                         g_free(tmp_listinfo->from_identity);
1483                                                         g_free(tmp_listinfo->to_identity);
1484                                                         g_free(tmp2_h323info->guid);
1485
1486                                                         list2 = g_list_first(tmp2_h323info->h245_list);
1487                                                         while (list2)
1488                                                         {
1489                                                                 h245_add=list2->data;
1490                                                                 g_free((void *)h245_add->h245_address.data);
1491                                                                 g_free(list2->data);
1492                                                                 list2 = g_list_next(list2);
1493                                                         }
1494                                                         g_list_free(tmp_h323info->h245_list);
1495                                                         tmp_h323info->h245_list = NULL;
1496                                                         g_free(tmp_listinfo->prot_info);
1497                                                         tapinfo->callsinfo_list = g_list_remove(tapinfo->callsinfo_list, tmp_listinfo);
1498                                                         break;
1499                                                 }
1500                                         }
1501                                 list = g_list_next (list);
1502                                 }
1503
1504                                 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"),
1505                                                           (h225_is_faststart==TRUE?"on":"off"));
1506                         } else if (h225_cstype == H225_RELEASE_COMPLET) {
1507                                 /* get the Q931 Release cause code */
1508                                 if (q931_cause_value != 0xFF){
1509                                         comment = g_strdup_printf("H225 Q931 Rel Cause (%i):%s", q931_cause_value,
1510                                                                   val_to_str_ext_const(q931_cause_value, &q931_cause_code_vals_ext, "<unknown>"));
1511                                 } else { /* Cause not set */
1512                                         comment = g_strdup("H225 No Q931 Rel Cause");
1513                                 }
1514                         }
1515                         /* change the graph comment for this new one */
1516                         if (comment != NULL) {
1517                                 change_frame_graph(tapinfo, h225_frame_num, NULL, comment);
1518                                 g_free(comment);
1519                         }
1520                 }
1521                 /* we reset the h225_frame_num to 0 because there could be empty h225 in the same frame
1522                    as non empty h225 (e.g connect), so we don't have to be here twice */
1523                 h225_frame_num = 0;
1524
1525         /* add staff to H245 */
1526         } else if (h245_labels.frame_num == q931_frame_num) {
1527         /* there are empty H225 frames that don't have guid (guaid=0) but they have h245 info,
1528            so the only way to match those frames is with the Q931 CRV number */
1529                 list = g_list_first(tapinfo->callsinfo_list);
1530                 while (list)
1531                 {
1532                         tmp_listinfo=list->data;
1533                         if (tmp_listinfo->protocol == VOIP_H323){
1534                                 tmp_h323info = tmp_listinfo->prot_info;
1535                                 if ( ((tmp_h323info->q931_crv == q931_crv) || (tmp_h323info->q931_crv2 == q931_crv)) && (q931_crv!=-1)){
1536                                         /* if the frame number exists in graph, append to it*/
1537                                         if (!append_to_frame_graph(tapinfo, q931_frame_num, NULL, NULL)) {
1538                                                 /* if not exist, add to the graph */
1539                                                 add_to_graph(tapinfo, pinfo, NULL, NULL, tmp_listinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
1540                                                 ++(tmp_listinfo->npackets);
1541                                                 /* increment the packets counter of all calls */
1542                                                 ++(tapinfo->npackets);
1543                                         }
1544
1545                                         /* Add the H245 info if exists to the Graph */
1546                                         h245_add_to_graph(pinfo->fd->num);
1547                                         break;
1548                                 }
1549                         }
1550                         list = g_list_next (list);
1551                 }
1552
1553         /* add staff to ACTRACE */
1554         } else if (actrace_frame_num == q931_frame_num) {
1555                 address pstn_add;
1556
1557                 comment = NULL;
1558                 callsinfo = NULL;
1559                 list = g_list_first(tapinfo->callsinfo_list);
1560                 while (list)
1561                 {
1562                         tmp_listinfo=list->data;
1563                         if ( tmp_listinfo->protocol == VOIP_AC_ISDN ){
1564                                 tmp_actrace_isdn_info = tmp_listinfo->prot_info;
1565                                 /* TODO: Also check the IP of the Blade, and if the call is complete (no active) */
1566                                 if ( (tmp_actrace_isdn_info->crv == q931_crv) && (tmp_actrace_isdn_info->trunk == actrace_trunk) ) {
1567                                         callsinfo = (voip_calls_info_t*)(list->data);
1568                                         break;
1569                                 }
1570                         }
1571                         list = g_list_next (list);
1572                 }
1573
1574                 SET_ADDRESS(&pstn_add, AT_STRINGZ, 5, g_strdup("PSTN"));
1575
1576                 /* if it is a new call, add it to the list */
1577                 if (!callsinfo) {
1578                         callsinfo = g_malloc0(sizeof(voip_calls_info_t));
1579                         callsinfo->call_active_state = VOIP_ACTIVE;
1580                         callsinfo->call_state = VOIP_CALL_SETUP;
1581                         callsinfo->from_identity=g_strdup(q931_calling_number);
1582                         callsinfo->to_identity=g_strdup(q931_called_number);
1583                         COPY_ADDRESS(&(callsinfo->initial_speaker),actrace_direction?&pstn_add:&(pinfo->src));
1584                         callsinfo->first_frame_num=pinfo->fd->num;
1585                         callsinfo->selected=FALSE;
1586                         callsinfo->start_abs=pinfo->fd->abs_ts;
1587                         callsinfo->start_rel=pinfo->fd->rel_ts;
1588                         callsinfo->protocol=VOIP_AC_ISDN;
1589                         callsinfo->prot_info=g_malloc(sizeof(actrace_isdn_calls_info_t));
1590                         callsinfo->free_prot_info = g_free;
1591                         tmp_actrace_isdn_info=callsinfo->prot_info;
1592                         tmp_actrace_isdn_info->crv=q931_crv;
1593                         tmp_actrace_isdn_info->trunk=actrace_trunk;
1594                         callsinfo->npackets = 0;
1595                         callsinfo->call_num = tapinfo->ncalls++;
1596                         tapinfo->callsinfo_list = g_list_append(tapinfo->callsinfo_list, callsinfo);
1597                 }
1598
1599                 callsinfo->stop_abs = pinfo->fd->abs_ts;
1600                 callsinfo->stop_rel = pinfo->fd->rel_ts;
1601                 callsinfo->last_frame_num=pinfo->fd->num;
1602                 ++(callsinfo->npackets);
1603                 /* increment the packets counter of all calls */
1604                 ++(tapinfo->npackets);
1605
1606                 switch(pi->message_type){
1607                 case Q931_SETUP:
1608                         comment = g_strdup_printf("AC_ISDN trunk:%u Calling: %s  Called:%s", actrace_trunk, q931_calling_number, q931_called_number);
1609                         callsinfo->call_state=VOIP_CALL_SETUP;
1610                         break;
1611                 case Q931_CONNECT:
1612                         callsinfo->call_state=VOIP_IN_CALL;
1613                         break;
1614                 case Q931_RELEASE_COMPLETE:
1615                 case Q931_RELEASE:
1616                 case Q931_DISCONNECT:
1617                         if (callsinfo->call_state==VOIP_CALL_SETUP){
1618                                 if (ADDRESSES_EQUAL(&(callsinfo->initial_speaker), actrace_direction?&pstn_add:&(pinfo->src) )){  /* forward direction */
1619                                         callsinfo->call_state=VOIP_CANCELLED;
1620                                 }
1621                                 else{                                                                                           /* reverse */
1622                                         callsinfo->call_state=VOIP_REJECTED;
1623                                         tapinfo->rejected_calls++;
1624                                 }
1625                         } else if ( (callsinfo->call_state!=VOIP_CANCELLED) && (callsinfo->call_state!=VOIP_REJECTED) ){
1626                                         callsinfo->call_state=VOIP_COMPLETED;
1627                                         tapinfo->completed_calls++;
1628                         }
1629                         if (q931_cause_value != 0xFF){
1630                                 comment = g_strdup_printf("AC_ISDN trunk:%u Q931 Rel Cause (%i):%s", actrace_trunk, q931_cause_value,
1631                                                           val_to_str_ext_const(q931_cause_value, &q931_cause_code_vals_ext, "<unknown>"));
1632                         } else { /* Cause not set */
1633                                 comment = g_strdup("AC_ISDN No Q931 Rel Cause");
1634                         }
1635                         break;
1636                 }
1637
1638                 if (!comment)
1639                         comment = g_strdup_printf("AC_ISDN  trunk:%u", actrace_trunk );
1640
1641                 add_to_graph(tapinfo, pinfo, val_to_str(pi->message_type, q931_message_type_vals, "<unknown>") , comment, callsinfo->call_num,
1642                                 actrace_direction?&pstn_add:&(pinfo->src),
1643                                 actrace_direction?&(pinfo->src):&pstn_add,
1644                                 1 );
1645
1646                 g_free(comment);
1647                 g_free((char *)pstn_add.data);
1648         }
1649
1650         tapinfo->redraw = TRUE;
1651
1652         return 1;  /* refresh output */
1653 }
1654
1655 /****************************************************************************/
1656 static gboolean have_q931_tap_listener=FALSE;
1657
1658 void
1659 q931_calls_init_tap(void)
1660 {
1661         GString *error_string;
1662
1663
1664         if(have_q931_tap_listener==FALSE)
1665         {
1666                 error_string = register_tap_listener("q931", &(the_tapinfo_struct.q931_dummy),
1667                         NULL,
1668                         0,
1669                         voip_calls_dlg_reset,
1670                         q931_calls_packet,
1671                         voip_calls_dlg_draw
1672                         );
1673
1674                 if (error_string != NULL) {
1675                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1676                                       "%s", error_string->str);
1677                         g_string_free(error_string, TRUE);
1678                         exit(1);
1679                 }
1680                 have_q931_tap_listener=TRUE;
1681         }
1682 }
1683
1684 /****************************************************************************/
1685
1686 void
1687 remove_tap_listener_q931_calls(void)
1688 {
1689         protect_thread_critical_region();
1690         remove_tap_listener(&(the_tapinfo_struct.q931_dummy));
1691         unprotect_thread_critical_region();
1692
1693         have_q931_tap_listener=FALSE;
1694 }
1695
1696 /****************************************************************************/
1697 /****************************TAP for H323 ***********************************/
1698 /****************************************************************************/
1699
1700 static void add_h245_Address(h323_calls_info_t *h323info,  h245_address_t *h245_address)
1701 {
1702         h323info->h245_list = g_list_append(h323info->h245_list, h245_address);
1703 }
1704
1705
1706 static void free_h225_info(gpointer p) {
1707         h323_calls_info_t *tmp_h323info = p;
1708
1709         g_free(tmp_h323info->guid);
1710
1711         if (tmp_h323info->h245_list) {
1712                 GList *list2 = g_list_first(tmp_h323info->h245_list);
1713                 while (list2)
1714                 {
1715                         h245_address_t *h245_add=list2->data;
1716                         g_free((void *)h245_add->h245_address.data);
1717                         g_free(list2->data);
1718                         list2 = g_list_next(list2);
1719                 }
1720
1721                 g_list_free(tmp_h323info->h245_list);
1722
1723         }
1724
1725         g_free(p);
1726 }
1727 /****************************************************************************/
1728 /* whenever a H225 packet is seen by the tap listener */
1729 static int
1730 H225calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *H225info)
1731 {
1732         voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
1733         voip_calls_info_t *tmp_listinfo;
1734         voip_calls_info_t *callsinfo = NULL;
1735         h323_calls_info_t *tmp_h323info = NULL;
1736         gchar *frame_label;
1737         gchar *comment;
1738         GList *list;
1739         h245_address_t *h245_add = NULL;
1740
1741         const h225_packet_info *pi = H225info;
1742
1743         /* if not guid and RAS and not LRQ, LCF or LRJ return because did not belong to a call */
1744         /* OR, if not guid and is H225 return because doesn't belong to a call */
1745         if ((memcmp(&pi->guid, &guid_allzero, GUID_LEN) == 0))
1746                 if ( ((pi->msg_type == H225_RAS) && ((pi->msg_tag < 18) || (pi->msg_tag > 20))) || (pi->msg_type != H225_RAS) )
1747                         return 0;
1748
1749         /* if it is RAS LCF or LRJ*/
1750         if ( (pi->msg_type == H225_RAS) && ((pi->msg_tag == 19) || (pi->msg_tag == 20))) {
1751                 /* if the LCF/LRJ doesn't match to a LRQ, just return */
1752                 if (!pi->request_available) return 0;
1753
1754                 /* check whether we already have a call with this request SeqNum */
1755                 list = g_list_first(tapinfo->callsinfo_list);
1756                 while (list)
1757                 {
1758                         tmp_listinfo=list->data;
1759                         g_assert(tmp_listinfo != NULL);
1760                         if (tmp_listinfo->protocol == VOIP_H323){
1761                                 tmp_h323info = tmp_listinfo->prot_info;
1762                                 if (tmp_h323info->requestSeqNum == pi->requestSeqNum) {
1763                                         callsinfo = (voip_calls_info_t*)(list->data);
1764                                         break;
1765                                 }
1766                         }
1767                         list = g_list_next (list);
1768                 }
1769         } else {
1770                 /* check whether we already have a call with this guid in the list */
1771                 list = g_list_first(tapinfo->callsinfo_list);
1772                 while (list)
1773                 {
1774                         tmp_listinfo=list->data;
1775                         if (tmp_listinfo->protocol == VOIP_H323){
1776                                 tmp_h323info = tmp_listinfo->prot_info;
1777                                 g_assert(tmp_h323info != NULL);
1778                                 if ( (memcmp(tmp_h323info->guid, &guid_allzero, GUID_LEN) != 0) && (memcmp(tmp_h323info->guid, &pi->guid,GUID_LEN)==0) ){
1779                                         callsinfo = (voip_calls_info_t*)(list->data);
1780                                         break;
1781                                 }
1782                         }
1783                         list = g_list_next (list);
1784                 }
1785         }
1786
1787         h225_cstype = pi->cs_type;
1788         h225_is_faststart = pi->is_faststart;
1789
1790         /* not in the list? then create a new entry */
1791         if (callsinfo==NULL){
1792                 callsinfo = g_malloc0(sizeof(voip_calls_info_t));
1793                 callsinfo->call_active_state = VOIP_ACTIVE;
1794                 callsinfo->call_state = VOIP_UNKNOWN;
1795                 callsinfo->from_identity=g_strdup("");
1796                 callsinfo->to_identity=g_strdup("");
1797                 COPY_ADDRESS(&(callsinfo->initial_speaker),&(pinfo->src));
1798                 callsinfo->selected=FALSE;
1799                 callsinfo->first_frame_num=pinfo->fd->num;
1800                 callsinfo->start_abs=pinfo->fd->abs_ts;
1801                 callsinfo->start_rel=pinfo->fd->rel_ts;
1802                 callsinfo->protocol=VOIP_H323;
1803                 callsinfo->prot_info=g_malloc(sizeof(h323_calls_info_t));
1804                 callsinfo->free_prot_info = free_h225_info;
1805
1806                 tmp_h323info = callsinfo->prot_info;
1807                 g_assert(tmp_h323info != NULL);
1808                 tmp_h323info->guid = g_memdup(&pi->guid, sizeof pi->guid);
1809                 tmp_h323info->h225SetupAddr.type = AT_NONE;
1810                 tmp_h323info->h225SetupAddr.len = 0;
1811                 tmp_h323info->h245_list = NULL;
1812                 tmp_h323info->is_faststart_Setup = FALSE;
1813                 tmp_h323info->is_faststart_Proc = FALSE;
1814                 tmp_h323info->is_h245Tunneling = FALSE;
1815                 tmp_h323info->is_h245 = FALSE;
1816                 tmp_h323info->q931_crv = -1;
1817                 tmp_h323info->q931_crv2 = -1;
1818                 tmp_h323info->requestSeqNum = 0;
1819                 callsinfo->call_num = tapinfo->ncalls++;
1820                 callsinfo->npackets = 0;
1821
1822                 tapinfo->callsinfo_list = g_list_append(tapinfo->callsinfo_list, callsinfo);
1823         }
1824
1825         if (callsinfo!=NULL){
1826
1827                 h225_frame_num = pinfo->fd->num;
1828                 h225_call_num = callsinfo->call_num;
1829
1830                 /* let's analyze the call state */
1831
1832                 callsinfo->stop_abs = pinfo->fd->abs_ts;
1833                 callsinfo->stop_rel = pinfo->fd->rel_ts;
1834                 callsinfo->last_frame_num=pinfo->fd->num;
1835                 ++(callsinfo->npackets);
1836                 /* increment the packets counter of all calls */
1837                 ++(tapinfo->npackets);
1838
1839
1840                 /* XXX: it is supposed to be initialized isn't it? */
1841                 g_assert(tmp_h323info != NULL);
1842
1843                 /* change the status */
1844                 if (pi->msg_type == H225_CS){
1845
1846                         /* this is still IPv4 only, because the dissector is */
1847                         if (pi->is_h245 == TRUE){
1848                                 h245_add = g_malloc(sizeof (h245_address_t));
1849                                 h245_add->h245_address.type=AT_IPv4;
1850                                 h245_add->h245_address.len=4;
1851                                 h245_add->h245_address.data = g_malloc(sizeof(pi->h245_address));
1852                                 memcpy((void *)(h245_add->h245_address.data), &(pi->h245_address), 4);
1853                                 h245_add->h245_port = pi->h245_port;
1854                                 add_h245_Address(tmp_h323info, h245_add);
1855                         }
1856
1857                         if (pi->cs_type != H225_RELEASE_COMPLET) tmp_h323info->is_h245Tunneling = pi->is_h245Tunneling;
1858
1859                         frame_label = g_strdup(pi->frame_label);
1860
1861                         switch(pi->cs_type){
1862                         case H225_SETUP:
1863                                 tmp_h323info->is_faststart_Setup = pi->is_faststart;
1864
1865                                 /* Set the Setup address if it was not set */
1866                                 if (tmp_h323info->h225SetupAddr.type == AT_NONE)
1867                                         COPY_ADDRESS(&(tmp_h323info->h225SetupAddr), &(pinfo->src));
1868                                 callsinfo->call_state=VOIP_CALL_SETUP;
1869                                 comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
1870                                                                                   (pi->is_faststart==TRUE?"on":"off"));
1871                                 break;
1872                         case H225_CONNECT:
1873                                 callsinfo->call_state=VOIP_IN_CALL;
1874                                 if (pi->is_faststart == TRUE) tmp_h323info->is_faststart_Proc = TRUE;
1875                                         comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
1876                                                                                           (pi->is_faststart==TRUE?"on":"off"));
1877                                 break;
1878                         case H225_RELEASE_COMPLET:
1879                                 if (callsinfo->call_state==VOIP_CALL_SETUP){
1880                                         if (ADDRESSES_EQUAL(&(tmp_h323info->h225SetupAddr),&(pinfo->src))){  /* forward direction */
1881                                                 callsinfo->call_state=VOIP_CANCELLED;
1882                                         }
1883                                         else{                                                                                           /* reverse */
1884                                                 callsinfo->call_state=VOIP_REJECTED;
1885                                                 tapinfo->rejected_calls++;
1886                                         }
1887                                 } else {
1888                                                 callsinfo->call_state=VOIP_COMPLETED;
1889                                                 tapinfo->completed_calls++;
1890                                 }
1891                                 comment = g_strdup("H225 No Q931 Rel Cause");
1892                                 break;
1893                         case H225_PROGRESS:
1894                         case H225_ALERTING:
1895                         case H225_CALL_PROCEDING:
1896                                 if (pi->is_faststart == TRUE) tmp_h323info->is_faststart_Proc = TRUE;
1897                                 comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
1898                                                                                   (pi->is_faststart==TRUE?"on":"off"));
1899                                 break;
1900                         default:
1901                                 comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
1902                                                                                   (pi->is_faststart==TRUE?"on":"off"));
1903
1904                         }
1905                 }
1906                 else if (pi->msg_type == H225_RAS){
1907                         switch(pi->msg_tag){
1908                         case 18:  /* LRQ */
1909                                 if (!pi->is_duplicate){
1910                                         g_free(callsinfo->to_identity);
1911                                         callsinfo->to_identity=g_strdup(pi->dialedDigits);
1912                                         tmp_h323info->requestSeqNum = pi->requestSeqNum;
1913                                 }
1914                         case 19: /* LCF */
1915                                 if (strlen(pi->dialedDigits))
1916                                         comment = g_strdup_printf("H225 RAS dialedDigits: %s", pi->dialedDigits);
1917                                 else
1918                                         comment = g_strdup("H225 RAS");
1919                                 break;
1920                         default:
1921                                 comment = g_strdup("H225 RAS");
1922                         }
1923                         frame_label = g_strdup(val_to_str_const(pi->msg_tag, h225_RasMessage_vals, "<unknown>"));
1924                 } else {
1925                         frame_label = g_strdup("H225: Unknown");
1926                         comment = NULL;
1927                 }
1928
1929                 /* add to graph analysis */
1930
1931                 /* if the frame number exists in graph, append to it*/
1932                 if (!append_to_frame_graph(tapinfo, pinfo->fd->num, pi->frame_label, comment)) {
1933                         /* if not exist, add to the graph */
1934                         add_to_graph(tapinfo, pinfo, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
1935                 }
1936
1937                 /* Add the H245 info if exists to the Graph */
1938                 h245_add_to_graph(pinfo->fd->num);
1939
1940                 g_free(frame_label);
1941                 g_free(comment);
1942         }
1943
1944         tapinfo->redraw = TRUE;
1945
1946         return 1;  /* refresh output */
1947 }
1948
1949
1950 /****************************************************************************/
1951 /* TAP INTERFACE */
1952 /****************************************************************************/
1953 static gboolean have_H225_tap_listener=FALSE;
1954 /****************************************************************************/
1955 void
1956 h225_calls_init_tap(void)
1957 {
1958         GString *error_string;
1959
1960         if(have_H225_tap_listener==FALSE)
1961         {
1962                 /* don't register tap listener, if we have it already */
1963                 error_string = register_tap_listener("h225", &(the_tapinfo_struct.h225_dummy), NULL,
1964                         0,
1965                         voip_calls_dlg_reset,
1966                         H225calls_packet,
1967                         voip_calls_dlg_draw
1968                         );
1969
1970                 if (error_string != NULL) {
1971                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1972                                       "%s", error_string->str);
1973                         g_string_free(error_string, TRUE);
1974                         exit(1);
1975                 }
1976                 have_H225_tap_listener=TRUE;
1977         }
1978 }
1979
1980 /****************************************************************************/
1981 void
1982 remove_tap_listener_h225_calls(void)
1983 {
1984         protect_thread_critical_region();
1985         remove_tap_listener(&(the_tapinfo_struct.h225_dummy));
1986         unprotect_thread_critical_region();
1987
1988         have_H225_tap_listener=FALSE;
1989 }
1990
1991 /* Add the h245 label info to the graph */
1992 void h245_add_to_graph(guint32 new_frame_num)
1993 {
1994         gint8 n;
1995
1996         if (new_frame_num != h245_labels.frame_num) return;
1997
1998         for (n=0; n<h245_labels.labels_count; n++) {
1999                 append_to_frame_graph(&the_tapinfo_struct, new_frame_num, h245_labels.labels[n].frame_label, h245_labels.labels[n].comment);
2000                 g_free(h245_labels.labels[n].frame_label);
2001                 h245_labels.labels[n].frame_label = NULL;
2002                 g_free(h245_labels.labels[n].comment);
2003                 h245_labels.labels[n].comment = NULL;
2004         }
2005         h245_labels.frame_num = 0;
2006         h245_labels.labels_count = 0;
2007 }
2008
2009 /* free the h245_labels if the frame number is different */
2010 static void h245_free_labels(guint32 new_frame_num)
2011 {
2012         gint8 n;
2013
2014         if (new_frame_num == h245_labels.frame_num) return;
2015
2016         for (n=0; n<h245_labels.labels_count; n++) {
2017                 g_free(h245_labels.labels[n].frame_label);
2018                 h245_labels.labels[n].frame_label = NULL;
2019                 g_free(h245_labels.labels[n].comment);
2020                 h245_labels.labels[n].comment = NULL;
2021         }
2022         h245_labels.frame_num = 0;
2023         h245_labels.labels_count = 0;
2024 }
2025
2026 /* add the frame_label and comment to h245_labels and free the actual one if it is different frame num */
2027 static void h245_add_label(guint32 new_frame_num, const gchar *frame_label, const gchar *comment)
2028 {
2029         h245_free_labels(new_frame_num);
2030
2031         h245_labels.frame_num = new_frame_num;
2032         h245_labels.labels[h245_labels.labels_count].frame_label = g_strdup(frame_label);
2033         h245_labels.labels[h245_labels.labels_count].comment = g_strdup(comment);
2034
2035         if (h245_labels.labels_count < (H245_MAX-1))
2036                 h245_labels.labels_count++;
2037
2038 }
2039
2040 /****************************************************************************/
2041 /* whenever a H245dg packet is seen by the tap listener (when H245 tunneling is ON) */
2042 static int
2043 H245dgcalls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *H245info)
2044 {
2045         voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
2046         voip_calls_info_t *tmp_listinfo;
2047         voip_calls_info_t *callsinfo = NULL;
2048         h323_calls_info_t *tmp_h323info;
2049         GList *list;
2050         GList *list2;
2051         h245_address_t *h245_add = NULL;
2052
2053         const h245_packet_info *pi = H245info;
2054
2055         /* check if Tunneling is OFF and we have a call with this H245 add */
2056         list = g_list_first(tapinfo->callsinfo_list);
2057         while (list)
2058         {
2059                 tmp_listinfo=list->data;
2060                 if (tmp_listinfo->protocol == VOIP_H323){
2061                         tmp_h323info = tmp_listinfo->prot_info;
2062
2063                         list2 = g_list_first(tmp_h323info->h245_list);
2064                         while (list2)
2065                         {
2066                                 h245_add=list2->data;
2067                                 if ( (ADDRESSES_EQUAL(&(h245_add->h245_address),&(pinfo->src)) && (h245_add->h245_port == pinfo->srcport))
2068                                         || (ADDRESSES_EQUAL(&(h245_add->h245_address),&(pinfo->dst)) && (h245_add->h245_port == pinfo->destport)) ){
2069                                         callsinfo = (voip_calls_info_t*)(list->data);
2070
2071                                         ++(callsinfo->npackets);
2072                                         /* increment the packets counter of all calls */
2073                                         ++(tapinfo->npackets);
2074
2075                                         break;
2076                                 }
2077                                 list2 = g_list_next(list2);
2078                         }
2079                         if (callsinfo!=NULL) break;
2080                 }
2081                 list = g_list_next(list);
2082         }
2083
2084         /* Tunnel is OFF, and we matched the h245 add so we add it to graph */
2085         if (callsinfo!=NULL){
2086                 ++(callsinfo->npackets);
2087                 /* increment the packets counter of all calls */
2088                 ++(tapinfo->npackets);
2089                 /* if the frame number exists in graph, append to it*/
2090                 if (!append_to_frame_graph(tapinfo, pinfo->fd->num, pi->frame_label, pi->comment)) {
2091                         /* if not exist, add to the graph */
2092                         add_to_graph(tapinfo, pinfo, pi->frame_label, pi->comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
2093                 }
2094         } else {
2095         /* Tunnel is ON, so we save the label info to use it into h225 or q931 tap. OR may be
2096                  tunnel OFF but we did not matched the h245 add, in this case nobady will set this label
2097                  since the frame_num will not match */
2098
2099                 h245_add_label(pinfo->fd->num, (gchar *) pi->frame_label, (gchar *) pi->comment);
2100         }
2101
2102         tapinfo->redraw = TRUE;
2103
2104         return 1;  /* refresh output */
2105 }
2106
2107
2108 /****************************************************************************/
2109 /* TAP INTERFACE */
2110 /****************************************************************************/
2111 static gboolean have_H245dg_tap_listener=FALSE;
2112 /****************************************************************************/
2113 void
2114 h245dg_calls_init_tap(void)
2115 {
2116         GString *error_string;
2117
2118         if(have_H245dg_tap_listener==FALSE)
2119         {
2120                 /* don't register tap listener, if we have it already */
2121                 error_string = register_tap_listener("h245dg", &(the_tapinfo_struct.h245dg_dummy), NULL,
2122                         0,
2123                         voip_calls_dlg_reset,
2124                         H245dgcalls_packet,
2125                         voip_calls_dlg_draw
2126                         );
2127
2128                 if (error_string != NULL) {
2129                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2130                                       "%s", error_string->str);
2131                         g_string_free(error_string, TRUE);
2132                         exit(1);
2133                 }
2134                 have_H245dg_tap_listener=TRUE;
2135         }
2136 }
2137
2138 /****************************************************************************/
2139 void
2140 remove_tap_listener_h245dg_calls(void)
2141 {
2142         protect_thread_critical_region();
2143         remove_tap_listener(&(the_tapinfo_struct.h245dg_dummy));
2144         unprotect_thread_critical_region();
2145
2146         have_H245dg_tap_listener=FALSE;
2147 }
2148
2149 /****************************************************************************/
2150 /****************************TAP for SDP PROTOCOL ***************************/
2151 /****************************************************************************/
2152 /* whenever a SDP packet is seen by the tap listener */
2153 static int
2154 SDPcalls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *SDPinfo)
2155 {
2156         voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
2157         const sdp_packet_info *pi = SDPinfo;
2158
2159         /* There are protocols like MGCP/SIP where the SDP is called before the tap for the
2160            MGCP/SIP packet, in those cases we assign the SPD summary to global lastSDPsummary
2161            to use it later
2162         */
2163         g_free(sdp_summary);
2164         sdp_frame_num = pinfo->fd->num;
2165         /* Append to graph the SDP summary if the packet exists */
2166         sdp_summary = g_strdup_printf("SDP (%s)", pi->summary_str);
2167         append_to_frame_graph(tapinfo, pinfo->fd->num, sdp_summary, NULL);
2168
2169         tapinfo->redraw = TRUE;
2170
2171         return 1;  /* refresh output */
2172 }
2173
2174
2175 /****************************************************************************/
2176 /* TAP INTERFACE */
2177 /****************************************************************************/
2178 static gboolean have_sdp_tap_listener=FALSE;
2179 /****************************************************************************/
2180 void
2181 sdp_calls_init_tap(void)
2182 {
2183         GString *error_string;
2184
2185         if(have_sdp_tap_listener==FALSE)
2186         {
2187                 /* don't register tap listener, if we have it already */
2188                 error_string = register_tap_listener("sdp", &(the_tapinfo_struct.sdp_dummy), NULL,
2189                         0,
2190                         voip_calls_dlg_reset,
2191                         SDPcalls_packet,
2192                         voip_calls_dlg_draw
2193                         );
2194
2195                 if (error_string != NULL) {
2196                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2197                                       "%s", error_string->str);
2198                         g_string_free(error_string, TRUE);
2199                         exit(1);
2200                 }
2201                 have_sdp_tap_listener=TRUE;
2202         }
2203 }
2204
2205 /****************************************************************************/
2206 void
2207 remove_tap_listener_sdp_calls(void)
2208 {
2209         protect_thread_critical_region();
2210         remove_tap_listener(&(the_tapinfo_struct.sdp_dummy));
2211         unprotect_thread_critical_region();
2212
2213         have_sdp_tap_listener=FALSE;
2214 }
2215
2216
2217
2218 /****************************************************************************/
2219 /* ***************************TAP for MGCP **********************************/
2220 /****************************************************************************/
2221
2222 /*
2223    This function will look for a signal/event in the SignalReq/ObsEvent string
2224    and return true if it is found
2225 */
2226 static gboolean isSignal(const gchar *signal_str_p, const gchar *signalStr)
2227 {
2228         gint i;
2229         gchar **resultArray;
2230
2231         /* if there is no signalStr, just return false */
2232         if (signalStr == NULL) return FALSE;
2233
2234         /* if are both "blank" return true */
2235         if ( (*signal_str_p == '\0') &&  (*signalStr == '\0') ) return TRUE;
2236
2237         /* look for signal in signalStr */
2238         resultArray = g_strsplit(signalStr, ",", 10);
2239
2240         for (i = 0; resultArray[i]; i++) {
2241                 g_strstrip(resultArray[i]);
2242                 if (strcmp(resultArray[i], signal_str_p) == 0) return TRUE;
2243         }
2244
2245         g_strfreev(resultArray);
2246
2247         return FALSE;
2248 }
2249
2250 /*
2251    This function will get the Caller ID info and replace the current string
2252    This is how it looks the caller Id: rg, ci(02/16/08/29, "3035550002","Ale Sipura 2")
2253 */
2254 static void mgcpCallerID(gchar *signalStr, gchar **callerId)
2255 {
2256         gchar **arrayStr;
2257
2258         /* if there is no signalStr, just return false */
2259         if (signalStr == NULL) return;
2260
2261         arrayStr = g_strsplit(signalStr, "\"", 10);
2262
2263         if (arrayStr[0] == NULL) return;
2264
2265         /* look for the ci signal */
2266         if (strstr(arrayStr[0], "ci(") && (arrayStr[1] != NULL) ) {
2267                 /* free the previous "From" field of the call, and assign the new */
2268                 g_free(*callerId);
2269                 *callerId = g_strdup(arrayStr[1]);
2270         }
2271         g_strfreev(arrayStr);
2272
2273         return;
2274 }
2275
2276
2277 /*
2278    This function will get the Dialed Digits and replace the current string
2279    This is how it looks the dialed digits 5,5,5,0,0,0,2,#,*
2280 */
2281 static void mgcpDialedDigits(gchar *signalStr, gchar **dialedDigits)
2282 {
2283         gchar *tmpStr;
2284         gchar resultStr[50];
2285         gint i,j;
2286
2287         /* if there is no signalStr, just return false */
2288         if (signalStr == NULL) return;
2289
2290         tmpStr = g_strdup(signalStr);
2291
2292         for ( i = 0 ; tmpStr[i] ; i++) {
2293                 switch (tmpStr[i]) {
2294                         case '0' : case '1' : case '2' : case '3' : case '4' :
2295                         case '5' : case '6' : case '7' : case '8' : case '9' :
2296                         case '#' : case '*' :
2297                                 break;
2298                         default:
2299                                 tmpStr[i] = '?';
2300                                 break;
2301                 }
2302         }
2303
2304         for (i = 0, j = 0; tmpStr[i] && i<50; i++) {
2305                 if (tmpStr[i] != '?')
2306                         resultStr[j++] = tmpStr[i];
2307         }
2308         resultStr[j] = '\0';
2309
2310         if (*resultStr == '\0') return;
2311
2312         g_free(*dialedDigits);
2313         *dialedDigits = g_strdup(resultStr);
2314         g_free(tmpStr);
2315
2316         return;
2317 }
2318
2319
2320
2321 /****************************************************************************/
2322 /* whenever a MGCP packet is seen by the tap listener */
2323 static int
2324 MGCPcalls_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *MGCPinfo)
2325 {
2326         voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
2327
2328         voip_calls_info_t *tmp_listinfo;
2329         voip_calls_info_t *callsinfo = NULL;
2330         mgcp_calls_info_t *tmp_mgcpinfo = NULL;
2331         GList *list;
2332         GList *listGraph;
2333         gchar *frame_label = NULL;
2334         gchar *comment = NULL;
2335         graph_analysis_item_t *gai;
2336         gboolean new = FALSE;
2337         gboolean fromEndpoint = FALSE; /* true for calls originated in Endpoints, false for calls from MGC */
2338         gdouble diff_time;
2339
2340         const mgcp_info_t *pi = MGCPinfo;
2341
2342
2343         if ((pi->mgcp_type == MGCP_REQUEST) && !pi->is_duplicate ){
2344                 /* check whether we already have a call with this Endpoint and it is active*/
2345                 list = g_list_first(tapinfo->callsinfo_list);
2346                 while (list)
2347                 {
2348                         tmp_listinfo=list->data;
2349                         if ((tmp_listinfo->protocol == VOIP_MGCP) && (tmp_listinfo->call_active_state == VOIP_ACTIVE)){
2350                                 tmp_mgcpinfo = tmp_listinfo->prot_info;
2351                                 if (pi->endpointId != NULL){
2352                                         if (g_ascii_strcasecmp(tmp_mgcpinfo->endpointId,pi->endpointId) == 0){
2353                                                 /*
2354                                                    check first if it is an ended call. We can still match packets to this Endpoint 2 seconds
2355                                                    after the call has been released
2356                                                 */
2357                                                 diff_time = nstime_to_sec(&pinfo->fd->rel_ts) - nstime_to_sec(&tmp_listinfo->stop_rel);
2358                                                 if ( ((tmp_listinfo->call_state == VOIP_CANCELLED) ||
2359                                                      (tmp_listinfo->call_state == VOIP_COMPLETED)  ||
2360                                                      (tmp_listinfo->call_state == VOIP_REJECTED)) &&
2361                                                        (diff_time > 2) )
2362                                                 {
2363                                                         tmp_listinfo->call_active_state = VOIP_INACTIVE;
2364                                                 } else {
2365                                                         callsinfo = (voip_calls_info_t*)(list->data);
2366                                                         break;
2367                                                 }
2368                                         }
2369                                 }
2370                         }
2371                         list = g_list_next (list);
2372                 }
2373
2374                 /* there is no call with this Endpoint, lets see if this a new call or not */
2375                 if (callsinfo == NULL){
2376                         if ( (strcmp(pi->code, "NTFY") == 0) && isSignal("hd", pi->observedEvents) ){ /* off hook transition */
2377                                 /* this is a new call from the Endpoint */
2378                                 fromEndpoint = TRUE;
2379                                 new = TRUE;
2380                         } else if (strcmp(pi->code, "CRCX") == 0){
2381                                 /* this is a new call from the MGC */
2382                                 fromEndpoint = FALSE;
2383                                 new = TRUE;
2384                         }
2385                         if (!new) return 0;
2386                 }
2387         } else if ( ((pi->mgcp_type == MGCP_RESPONSE) && pi->request_available) ||
2388                         ((pi->mgcp_type == MGCP_REQUEST) && pi->is_duplicate) ) {
2389                 /* if it is a response OR if it is a duplicated Request, lets look in the Graph to see
2390                    if there is a request that matches */
2391                 listGraph = g_list_first(tapinfo->graph_analysis->list);
2392                 while (listGraph)
2393                 {
2394                         gai = listGraph->data;
2395                         if (gai->frame_num == pi->req_num){
2396                                 /* there is a request that match, so look the associated call with this call_num */
2397                                 list = g_list_first(tapinfo->callsinfo_list);
2398                                 while (list)
2399                                 {
2400                                         tmp_listinfo=list->data;
2401                                         if (tmp_listinfo->protocol == VOIP_MGCP){
2402                                                 if (tmp_listinfo->call_num == gai->conv_num){
2403                                                         tmp_mgcpinfo = tmp_listinfo->prot_info;
2404                                                         callsinfo = (voip_calls_info_t*)(list->data);
2405                                                         break;
2406                                                 }
2407                                         }
2408                                         list = g_list_next (list);
2409                                 }
2410                                 if (callsinfo != NULL) break;
2411                         }
2412                         listGraph = g_list_next(listGraph);
2413                 }
2414                 /* if there is not a matching request, just return */
2415                 if (callsinfo == NULL) return 0;
2416         } else return 0;
2417
2418         /* not in the list? then create a new entry */
2419         if (callsinfo==NULL){
2420                 callsinfo = g_malloc0(sizeof(voip_calls_info_t));
2421                 callsinfo->call_active_state = VOIP_ACTIVE;
2422                 callsinfo->call_state = VOIP_CALL_SETUP;
2423                 if (fromEndpoint) {
2424                         callsinfo->from_identity=g_strdup(pi->endpointId);
2425                         callsinfo->to_identity=g_strdup("");
2426                 } else {
2427                         callsinfo->from_identity=g_strdup("");
2428                         callsinfo->to_identity=g_strdup(pi->endpointId);
2429                 }
2430                 COPY_ADDRESS(&(callsinfo->initial_speaker),&(pinfo->src));
2431                 callsinfo->first_frame_num=pinfo->fd->num;
2432                 callsinfo->selected=FALSE;
2433                 callsinfo->start_abs=pinfo->fd->abs_ts;
2434                 callsinfo->start_rel=pinfo->fd->rel_ts;
2435                 callsinfo->protocol=VOIP_MGCP;
2436                 callsinfo->prot_info=g_malloc(sizeof(mgcp_calls_info_t));
2437                 callsinfo->free_prot_info = g_free;
2438                 tmp_mgcpinfo=callsinfo->prot_info;
2439                 tmp_mgcpinfo->endpointId = g_strdup(pi->endpointId);
2440                 tmp_mgcpinfo->fromEndpoint = fromEndpoint;
2441                 callsinfo->npackets = 0;
2442                 callsinfo->call_num = tapinfo->ncalls++;
2443                 tapinfo->callsinfo_list = g_list_append(tapinfo->callsinfo_list, callsinfo);
2444         }
2445
2446         g_assert(tmp_mgcpinfo != NULL);
2447
2448         /* change call state and add to graph */
2449         switch (pi->mgcp_type)
2450         {
2451         case MGCP_REQUEST:
2452                 if ( (strcmp(pi->code, "NTFY") == 0) && (pi->observedEvents != NULL) ){
2453                         frame_label = g_strdup_printf("%s ObsEvt:%s",pi->code, pi->observedEvents);
2454
2455                         if (tmp_mgcpinfo->fromEndpoint){
2456                                 /* use the Dialed digits to fill the "To" for the call, but use the first NTFY */
2457                                 if (callsinfo->to_identity[0] == '\0') mgcpDialedDigits(pi->observedEvents, &(callsinfo->to_identity));
2458
2459                         /* from MGC and the user picked up, the call is connected */
2460                         } else if (isSignal("hd", pi->observedEvents))
2461                                 callsinfo->call_state=VOIP_IN_CALL;
2462
2463                         /* hung up signal */
2464                         if (isSignal("hu", pi->observedEvents)) {
2465                                 if ((callsinfo->call_state == VOIP_CALL_SETUP) || (callsinfo->call_state == VOIP_RINGING)){
2466                                         callsinfo->call_state = VOIP_CANCELLED;
2467                                 } else {
2468                                         callsinfo->call_state = VOIP_COMPLETED;
2469                                 }
2470                         }
2471
2472                 } else if (strcmp(pi->code, "RQNT") == 0) {
2473                         /* for calls from Endpoint: if there is a "no signal" RQNT and the call was RINGING, we assume this is the CONNECT */
2474                         if ( tmp_mgcpinfo->fromEndpoint && isSignal("", pi->signalReq) && (callsinfo->call_state == VOIP_RINGING) ) {
2475                                         callsinfo->call_state = VOIP_IN_CALL;
2476                         }
2477
2478                         /* if there is ringback or ring tone, change state to ringing */
2479                         if ( isSignal("rg", pi->signalReq) || isSignal("rt", pi->signalReq) ) {
2480                                         callsinfo->call_state = VOIP_RINGING;
2481                         }
2482
2483                         /* if there is a Busy or ReorderTone, and the call was Ringing or Setup the call is Rejected */
2484                         if ( (isSignal("ro", pi->signalReq) || isSignal("bz", pi->signalReq)) && ((callsinfo->call_state == VOIP_CALL_SETUP) || (callsinfo->call_state == VOIP_RINGING)) ) {
2485                                         callsinfo->call_state = VOIP_REJECTED;
2486                         }
2487
2488                         if (pi->signalReq != NULL)
2489                                 frame_label = g_strdup_printf("%s%sSigReq:%s",pi->code, (pi->hasDigitMap == TRUE)?" DigitMap ":"", pi->signalReq);
2490                         else
2491                                 frame_label = g_strdup_printf("%s%s",pi->code, (pi->hasDigitMap == TRUE)?" DigitMap ":"");
2492
2493                         /* use the CallerID info to fill the "From" for the call */
2494                         if (!tmp_mgcpinfo->fromEndpoint) mgcpCallerID(pi->signalReq, &(callsinfo->from_identity));
2495
2496                 } else if (strcmp(pi->code, "DLCX") == 0) {
2497                         /*
2498                           if there is a DLCX in a call To an Endpoint and the call was not connected, we use
2499                           the DLCX as the end of the call
2500                         */
2501                         if (!tmp_mgcpinfo->fromEndpoint){
2502                                 if ((callsinfo->call_state == VOIP_CALL_SETUP) || (callsinfo->call_state == VOIP_RINGING)){
2503                                         callsinfo->call_state = VOIP_CANCELLED;
2504                                 }
2505                         }
2506                 }
2507
2508                 if (frame_label == NULL) frame_label = g_strdup(pi->code);
2509                 break;
2510         case MGCP_RESPONSE:
2511                 frame_label = g_strdup_printf("%u (%s)",pi->rspcode, pi->code);
2512                 break;
2513         case MGCP_OTHERS:
2514                 /* XXX what to do? */
2515                 break;
2516         }
2517
2518
2519         comment = g_strdup_printf("MGCP %s %s%s", tmp_mgcpinfo->endpointId, (pi->mgcp_type == MGCP_REQUEST)?"Request":"Response", pi->is_duplicate?" Duplicate":"");
2520
2521         callsinfo->stop_abs = pinfo->fd->abs_ts;
2522         callsinfo->stop_rel = pinfo->fd->rel_ts;
2523         callsinfo->last_frame_num=pinfo->fd->num;
2524         ++(callsinfo->npackets);
2525         /* increment the packets counter of all calls */
2526         ++(tapinfo->npackets);
2527
2528         /* add to the graph */
2529         add_to_graph(tapinfo, pinfo, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
2530         g_free(comment);
2531         g_free(frame_label);
2532
2533         /* add SDP info if apply */
2534         if ( (sdp_summary != NULL) && (sdp_frame_num == pinfo->fd->num) ){
2535                         append_to_frame_graph(tapinfo, pinfo->fd->num, sdp_summary, NULL);
2536                         g_free(sdp_summary);
2537                         sdp_summary = NULL;
2538         }
2539
2540         tapinfo->redraw = TRUE;
2541
2542         return 1;  /* refresh output */
2543 }
2544
2545
2546 /****************************************************************************/
2547 /* TAP INTERFACE */
2548 /****************************************************************************/
2549 static gboolean have_MGCP_tap_listener=FALSE;
2550 /****************************************************************************/
2551 void
2552 mgcp_calls_init_tap(void)
2553 {
2554         GString *error_string;
2555
2556         if(have_MGCP_tap_listener==FALSE)
2557         {
2558                 /*
2559                  * Don't register the tap listener if we have it already.
2560                  * We set TL_REQUIRES_PROTO_TREE to force a non-null "tree"
2561                  * in the MGCP dissector; otherwise, the dissector
2562                  * doesn't fill in the info passed to the tap's packet
2563                  * routine.
2564                  */
2565                 error_string = register_tap_listener("mgcp",
2566                         &(the_tapinfo_struct.mgcp_dummy),
2567                         NULL,
2568                         TL_REQUIRES_PROTO_TREE,
2569                         voip_calls_dlg_reset,
2570                         MGCPcalls_packet,
2571                         voip_calls_dlg_draw
2572                         );
2573                 if (error_string != NULL) {
2574                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2575                                       "%s", error_string->str);
2576                         g_string_free(error_string, TRUE);
2577                         exit(1);
2578                 }
2579                 have_MGCP_tap_listener=TRUE;
2580         }
2581 }
2582
2583 /****************************************************************************/
2584 void
2585 remove_tap_listener_mgcp_calls(void)
2586 {
2587         protect_thread_critical_region();
2588         remove_tap_listener(&(the_tapinfo_struct.mgcp_dummy));
2589         unprotect_thread_critical_region();
2590
2591         have_MGCP_tap_listener=FALSE;
2592 }
2593
2594
2595 /****************************************************************************/
2596 /****************************TAP for ACTRACE (AudioCodes trace)**************/
2597 /****************************************************************************/
2598
2599 /* whenever a ACTRACE packet is seen by the tap listener */
2600 static int
2601 ACTRACEcalls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *ACTRACEinfo)
2602 {
2603         voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
2604         const actrace_info_t *pi = ACTRACEinfo;
2605         GList *list;
2606         actrace_cas_calls_info_t *tmp_actrace_cas_info;
2607         voip_calls_info_t *tmp_listinfo;
2608         voip_calls_info_t *callsinfo = NULL;
2609
2610
2611         actrace_frame_num = pinfo->fd->num;
2612         actrace_trunk = pi->trunk;
2613         actrace_direction = pi->direction;
2614
2615         if (pi->type == 1){ /* is CAS protocol */
2616                 address pstn_add;
2617                 gchar *comment = NULL;
2618
2619                 callsinfo = NULL;
2620                 list = g_list_first(tapinfo->callsinfo_list);
2621                 while (list)
2622                 {
2623                         tmp_listinfo=list->data;
2624                         if ( tmp_listinfo->protocol == VOIP_AC_CAS ){
2625                                 tmp_actrace_cas_info = tmp_listinfo->prot_info;
2626                                 /* TODO: Also check the IP of the Blade, and if the call is complete (no active) */
2627                                 if ( (tmp_actrace_cas_info->bchannel == pi->cas_bchannel) && (tmp_actrace_cas_info->trunk == actrace_trunk) ) {
2628                                         callsinfo = (voip_calls_info_t*)(list->data);
2629                                         break;
2630                                 }
2631                         }
2632                         list = g_list_next (list);
2633                 }
2634
2635                 SET_ADDRESS(&pstn_add, AT_STRINGZ, 5, "PSTN");
2636
2637                 /* if it is a new call, add it to the list */
2638                 if (!callsinfo) {
2639                         callsinfo = g_malloc0(sizeof(voip_calls_info_t));
2640                         callsinfo->call_active_state = VOIP_ACTIVE;
2641                         callsinfo->call_state = VOIP_CALL_SETUP;
2642                         callsinfo->from_identity=g_strdup("N/A");
2643                         callsinfo->to_identity=g_strdup("N/A");
2644                         COPY_ADDRESS(&(callsinfo->initial_speaker),actrace_direction?&pstn_add:&(pinfo->src));
2645                         callsinfo->first_frame_num=pinfo->fd->num;
2646                         callsinfo->selected=FALSE;
2647                         callsinfo->start_abs=pinfo->fd->abs_ts;
2648                         callsinfo->start_rel=pinfo->fd->rel_ts;
2649                         callsinfo->protocol=VOIP_AC_CAS;
2650                         callsinfo->prot_info=g_malloc(sizeof(actrace_cas_calls_info_t));
2651                         callsinfo->free_prot_info = g_free;
2652
2653                         tmp_actrace_cas_info=callsinfo->prot_info;
2654                         tmp_actrace_cas_info->bchannel=pi->cas_bchannel;
2655                         tmp_actrace_cas_info->trunk=actrace_trunk;
2656                         callsinfo->npackets = 0;
2657                         callsinfo->call_num = tapinfo->ncalls++;
2658                         tapinfo->callsinfo_list = g_list_append(tapinfo->callsinfo_list, callsinfo);
2659                 }
2660
2661                 callsinfo->stop_abs = pinfo->fd->abs_ts;
2662                 callsinfo->stop_rel = pinfo->fd->rel_ts;
2663                 callsinfo->last_frame_num=pinfo->fd->num;
2664                 ++(callsinfo->npackets);
2665                 /* increment the packets counter of all calls */
2666                 ++(tapinfo->npackets);
2667
2668                 comment = g_strdup_printf("AC_CAS  trunk:%u", actrace_trunk);
2669
2670                 add_to_graph(tapinfo, pinfo, pi->cas_frame_label, comment, callsinfo->call_num,
2671                                 actrace_direction?&pstn_add:&(pinfo->src),
2672                                 actrace_direction?&(pinfo->src):&pstn_add,
2673                                 1 );
2674
2675                 g_free(comment);
2676         }
2677
2678         tapinfo->redraw = TRUE;
2679
2680         return 1;  /* refresh output */
2681 }
2682
2683
2684 /****************************************************************************/
2685 /* TAP INTERFACE */
2686 /****************************************************************************/
2687 static gboolean have_actrace_tap_listener=FALSE;
2688 /****************************************************************************/
2689 void
2690 actrace_calls_init_tap(void)
2691 {
2692         GString *error_string;
2693
2694         if(have_actrace_tap_listener==FALSE)
2695         {
2696                 /* don't register tap listener, if we have it already */
2697                 error_string = register_tap_listener("actrace", &(the_tapinfo_struct.actrace_dummy), NULL,
2698                         0,
2699                         voip_calls_dlg_reset,
2700                         ACTRACEcalls_packet,
2701                         voip_calls_dlg_draw
2702                         );
2703
2704                 if (error_string != NULL) {
2705                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2706                                       "%s", error_string->str);
2707                         g_string_free(error_string, TRUE);
2708                         exit(1);
2709                 }
2710                 have_actrace_tap_listener=TRUE;
2711         }
2712 }
2713
2714 /****************************************************************************/
2715 void
2716 remove_tap_listener_actrace_calls(void)
2717 {
2718         protect_thread_critical_region();
2719         remove_tap_listener(&(the_tapinfo_struct.actrace_dummy));
2720         unprotect_thread_critical_region();
2721
2722         have_actrace_tap_listener=FALSE;
2723 }
2724
2725
2726 /****************************************************************************/
2727 /**************************** TAP for H248/MEGACO **********************************/
2728 /****************************************************************************/
2729 static gboolean have_h248_tap_listener = FALSE;
2730 static gboolean have_megaco_tap_listener = FALSE;
2731
2732 #define gcp_is_req(type) ( type == GCP_CMD_ADD_REQ || type == GCP_CMD_MOVE_REQ || type == GCP_CMD_MOD_REQ || \
2733                                                         type == GCP_CMD_SUB_REQ || type == GCP_CMD_AUDITCAP_REQ || type == GCP_CMD_AUDITVAL_REQ || \
2734                                                         type == GCP_CMD_NOTIFY_REQ || type == GCP_CMD_SVCCHG_REQ || type == GCP_CMD_TOPOLOGY_REQ || \
2735                                                         type == GCP_CMD_CTX_ATTR_AUDIT_REQ )
2736
2737 static int h248_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *prot_info) {
2738         voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
2739         const gcp_cmd_t *cmd = prot_info;
2740         GList *list;
2741         voip_calls_info_t *callsinfo = NULL;
2742         address *mgw;
2743         address *mgc;
2744         gchar mgw_addr[128];
2745
2746         if (cmd->ctx->id == NULL_CONTEXT || cmd->ctx->id == ALL_CONTEXTS ) {
2747                 return 0;
2748         }
2749
2750         if ( gcp_is_req(cmd->type) ) {
2751                 mgw = &(pinfo->dst);
2752                 mgc = &(pinfo->src);
2753         } else {
2754                 mgc = &(pinfo->dst);
2755                 mgw = &(pinfo->src);
2756         }
2757
2758         address_to_str_buf(mgw, mgw_addr, 128);
2759
2760         /* check whether we already have this context in the list */
2761         list = g_list_first(tapinfo->callsinfo_list);
2762         while (list)
2763         {
2764                 voip_calls_info_t* tmp_listinfo = list->data;
2765
2766                 if (tmp_listinfo->protocol == TEL_H248){
2767                         if (tmp_listinfo->prot_info == cmd->ctx){
2768                                 callsinfo = (voip_calls_info_t*)(list->data);
2769                                 break;
2770                         }
2771                 }
2772                 list = g_list_next (list);
2773         }
2774
2775         if (callsinfo==NULL){
2776
2777                 callsinfo = g_malloc0(sizeof(voip_calls_info_t));
2778                 callsinfo->call_state = VOIP_NO_STATE;
2779                 callsinfo->call_active_state = VOIP_ACTIVE;
2780                 callsinfo->from_identity = g_strdup_printf("%s : %.8x", mgw_addr, cmd->ctx->id);
2781                 callsinfo->to_identity = g_strdup("");
2782                 callsinfo->prot_info = cmd->ctx;
2783                 callsinfo->free_prot_info = NULL;
2784
2785                 callsinfo->npackets = 1;
2786                 callsinfo->first_frame_num=pinfo->fd->num;
2787                 callsinfo->last_frame_num=pinfo->fd->num;
2788
2789                 COPY_ADDRESS(&(callsinfo->initial_speaker), mgc);
2790
2791                 callsinfo->protocol = TEL_H248;
2792                 callsinfo->call_num = tapinfo->ncalls++;
2793                 callsinfo->start_abs = pinfo->fd->abs_ts;
2794                 callsinfo->start_rel = pinfo->fd->rel_ts;
2795                 callsinfo->stop_abs = pinfo->fd->abs_ts;
2796                 callsinfo->stop_rel = pinfo->fd->rel_ts;
2797
2798                 callsinfo->selected = FALSE;
2799
2800                 tapinfo->callsinfo_list = g_list_append(tapinfo->callsinfo_list, callsinfo);
2801
2802         } else {
2803                 GString *s = g_string_new("");
2804                 gcp_terms_t *ctx_term;
2805
2806                 g_free(callsinfo->from_identity);
2807                 callsinfo->from_identity = g_strdup_printf("%s : %.8x", mgw_addr, ((gcp_ctx_t*)callsinfo->prot_info)->id);
2808
2809                 g_free(callsinfo->to_identity);
2810
2811                 for (ctx_term = ((gcp_ctx_t*)callsinfo->prot_info)->terms.next;
2812                          ctx_term;
2813                          ctx_term = ctx_term->next ) {
2814                         if ( ctx_term->term && ctx_term->term->str) {
2815                                 g_string_append_printf(s," %s",ctx_term->term->str);
2816                         }
2817                 }
2818
2819                 callsinfo->to_identity = s->str;
2820                 g_string_free(s,FALSE);
2821
2822                 callsinfo->stop_abs = pinfo->fd->abs_ts;
2823                 callsinfo->stop_rel = pinfo->fd->rel_ts;
2824                 callsinfo->last_frame_num=pinfo->fd->num;
2825                 ++(callsinfo->npackets);
2826         }
2827
2828         add_to_graph(tapinfo, pinfo, cmd->str ? cmd->str : "unknown Msg",
2829                                  ep_strdup_printf("TrxId = %u, CtxId = %.8x",cmd->trx->id,cmd->ctx->id),
2830                                  callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
2831
2832         ++(tapinfo->npackets);
2833
2834         tapinfo->redraw = TRUE;
2835
2836         return 1;
2837 }
2838
2839 void h248_calls_init_tap(void)
2840 {
2841         GString *error_string;
2842
2843
2844         if(have_megaco_tap_listener==FALSE)
2845         {
2846                 error_string = register_tap_listener("megaco", &(the_tapinfo_struct.megaco_dummy),
2847                         NULL,
2848                         0,
2849                         voip_calls_dlg_reset,
2850                         h248_calls_packet,
2851                         voip_calls_dlg_draw);
2852
2853                 if (error_string != NULL) {
2854                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2855                                       "%s", error_string->str);
2856                         g_string_free(error_string, TRUE);
2857                         exit(1);
2858                 }
2859
2860                 have_megaco_tap_listener=TRUE;
2861         }
2862
2863         if(have_h248_tap_listener==FALSE)
2864         {
2865                 error_string = register_tap_listener("h248", &(the_tapinfo_struct.h248_dummy),
2866                         NULL,
2867                         0,
2868                         voip_calls_dlg_reset,
2869                         h248_calls_packet,
2870                         voip_calls_dlg_draw);
2871
2872                 if (error_string != NULL) {
2873                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2874                                       "%s", error_string->str);
2875                         g_string_free(error_string, TRUE);
2876                         exit(1);
2877                 }
2878
2879                 have_h248_tap_listener=TRUE;
2880         }
2881 }
2882
2883 void
2884 remove_tap_listener_h248_calls(void)
2885 {
2886         protect_thread_critical_region();
2887         remove_tap_listener(&(the_tapinfo_struct.h248_dummy));
2888         remove_tap_listener(&(the_tapinfo_struct.megaco_dummy));
2889         unprotect_thread_critical_region();
2890
2891         have_megaco_tap_listener=FALSE;
2892         have_h248_tap_listener=FALSE;
2893 }
2894
2895 /****************************************************************************/
2896 /**************************** TAP for SCCP and SUA **********************************/
2897 /**************************** ( RANAP and BSSAP ) **********************************/
2898 /****************************************************************************/
2899
2900 static gboolean have_sccp_tap_listener = FALSE;
2901 static gboolean have_sua_tap_listener = FALSE;
2902
2903 static const voip_protocol sccp_proto_map[] = {
2904         TEL_SCCP,
2905         TEL_BSSMAP,
2906         TEL_RANAP
2907 };
2908 #define SP2VP(ap) ((ap) < SCCP_PLOAD_NUM_PLOADS ? sccp_proto_map[(ap)] : TEL_SCCP)
2909 const value_string* sccp_payload_values;
2910
2911 static int sccp_calls(packet_info *pinfo, const void *prot_info) {
2912         voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
2913         const sccp_msg_info_t* msg = prot_info;
2914         sccp_assoc_info_t* assoc = msg->data.co.assoc;
2915         GList *list;
2916         voip_calls_info_t *callsinfo = NULL;
2917         const gchar *label = NULL;
2918         const gchar *comment = NULL;
2919         /* check whether we already have this assoc in the list */
2920
2921         for(list = g_list_first(tapinfo->callsinfo_list) ; list ; list = g_list_next (list) ) {
2922                 if ( ((voip_calls_info_t*)(list->data))->prot_info == assoc ){
2923                                 callsinfo = (voip_calls_info_t*)(list->data);
2924                                 break;
2925                 }
2926         }
2927
2928         if (callsinfo==NULL){
2929                 callsinfo = g_malloc0(sizeof(voip_calls_info_t));
2930                 callsinfo->call_state = VOIP_CALL_SETUP;
2931                 callsinfo->call_active_state = VOIP_ACTIVE;
2932                 if ( assoc->calling_party ) {
2933                         callsinfo->from_identity =  g_strdup(assoc->calling_party);
2934                 } else {
2935                         callsinfo->from_identity =  g_strdup("Unknown");
2936                 }
2937
2938                 if ( assoc->called_party ) {
2939                         callsinfo->to_identity =  g_strdup(assoc->called_party);
2940                 } else {
2941                         callsinfo->to_identity =  g_strdup("Unknown");
2942                 }
2943
2944                 callsinfo->prot_info = (void*)assoc;
2945                 callsinfo->free_prot_info = NULL;
2946
2947                 callsinfo->npackets = 1;
2948                 callsinfo->first_frame_num=pinfo->fd->num;
2949                 callsinfo->last_frame_num=pinfo->fd->num;
2950
2951                 COPY_ADDRESS(&(callsinfo->initial_speaker), &(pinfo->src));
2952
2953                 callsinfo->protocol =   SP2VP(assoc->payload);
2954                 callsinfo->start_abs = pinfo->fd->abs_ts;
2955                 callsinfo->start_rel = pinfo->fd->rel_ts;
2956                 callsinfo->stop_abs = pinfo->fd->abs_ts;
2957                 callsinfo->stop_rel = pinfo->fd->rel_ts;
2958
2959                 callsinfo->selected = FALSE;
2960                 callsinfo->call_num = tapinfo->ncalls++;
2961
2962                 tapinfo->callsinfo_list = g_list_append(tapinfo->callsinfo_list, callsinfo);
2963         } else {
2964
2965                 if ( assoc->calling_party ) {
2966                         g_free(callsinfo->from_identity);
2967                         callsinfo->from_identity =  g_strdup(assoc->calling_party);
2968                 }
2969
2970                 if ( assoc->called_party ) {
2971                         g_free(callsinfo->to_identity);
2972                         callsinfo->to_identity =  g_strdup(assoc->called_party);
2973                 }
2974
2975                 callsinfo->protocol =  SP2VP(assoc->payload);
2976                 callsinfo->stop_abs = pinfo->fd->abs_ts;
2977                 callsinfo->stop_rel = pinfo->fd->rel_ts;
2978                 callsinfo->last_frame_num=pinfo->fd->num;
2979                 ++(callsinfo->npackets);
2980
2981                 switch (msg->type) {
2982                         case SCCP_MSG_TYPE_CC:
2983                                 callsinfo->call_state = VOIP_IN_CALL;
2984                                 break;
2985                         case SCCP_MSG_TYPE_RLC:
2986                                 callsinfo->call_state = VOIP_COMPLETED;
2987                                 callsinfo->call_active_state = VOIP_INACTIVE;
2988                                 break;
2989                         default:
2990                                 break;
2991                 }
2992         }
2993
2994         if (msg->data.co.label) {
2995                 label = msg->data.co.label;
2996         } else {
2997                 label = val_to_str(msg->type, sccp_payload_values, "Unknown(%d)");
2998         }
2999
3000         if (msg->data.co.comment) {
3001                 comment = msg->data.co.comment;
3002         } else {
3003                 comment = NULL;
3004         }
3005
3006         add_to_graph(tapinfo, pinfo, label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3007
3008         ++(tapinfo->npackets);
3009
3010         tapinfo->redraw = TRUE;
3011
3012         return 1;
3013 }
3014
3015 static int sccp_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *prot_info) {
3016         sccp_payload_values = sccp_message_type_acro_values;
3017         return sccp_calls(pinfo, prot_info);
3018 }
3019
3020
3021 static int sua_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *prot_info) {
3022         sccp_payload_values = sua_co_class_type_acro_values;
3023         return sccp_calls(pinfo, prot_info);
3024 }
3025
3026
3027 void sccp_calls_init_tap(void)
3028 {
3029         GString *error_string;
3030
3031         if(have_sccp_tap_listener==FALSE)
3032         {
3033                 error_string = register_tap_listener("sccp", &(the_tapinfo_struct.sccp_dummy),
3034                         NULL,
3035                         0,
3036                         voip_calls_dlg_reset,
3037                         sccp_calls_packet,
3038                         voip_calls_dlg_draw);
3039
3040                 if (error_string != NULL) {
3041                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3042                                       "%s", error_string->str);
3043                         g_string_free(error_string, TRUE);
3044                         exit(1);
3045                 }
3046
3047                 have_sccp_tap_listener=TRUE;
3048         }
3049
3050         if(have_sua_tap_listener==FALSE)
3051         {
3052                 error_string = register_tap_listener("sua", &(the_tapinfo_struct.sua_dummy),
3053                         NULL,
3054                         0,
3055                         voip_calls_dlg_reset,
3056                         sua_calls_packet,
3057                         voip_calls_dlg_draw);
3058
3059                 if (error_string != NULL) {
3060                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3061                                       "%s", error_string->str);
3062                         g_string_free(error_string, TRUE);
3063                         exit(1);
3064                 }
3065
3066                 have_sua_tap_listener=TRUE;
3067         }
3068
3069 }
3070
3071 void
3072 remove_tap_listener_sccp_calls(void)
3073 {
3074         protect_thread_critical_region();
3075         remove_tap_listener(&(the_tapinfo_struct.sccp_dummy));
3076         unprotect_thread_critical_region();
3077
3078         have_sccp_tap_listener=FALSE;
3079         have_sua_tap_listener=FALSE;
3080 }
3081
3082
3083 /****************************************************************************/
3084 /****************************TAP for UNISTIM ********************************/
3085 /****************************************************************************/
3086
3087 static int
3088 unistim_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *unistim_info)
3089 {
3090         voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
3091         voip_calls_info_t *tmp_listinfo;
3092         voip_calls_info_t *callsinfo = NULL;
3093         unistim_info_t *tmp_unistim_info = NULL;
3094         GList *list = NULL;
3095         GString *g_tmp = NULL;
3096         gchar *frame_label = NULL;
3097         gchar *comment = NULL;
3098
3099         /* Fetch specific packet infos */
3100         const unistim_info_t *pi = unistim_info;
3101
3102         /* Init gstring */
3103         g_tmp = g_string_new(NULL);
3104
3105         /* Check to see if this is a dup */
3106         list = g_list_first(tapinfo->callsinfo_list);
3107
3108         while(list)
3109         {
3110                 tmp_listinfo = list->data;
3111
3112                 if(tmp_listinfo->protocol == VOIP_UNISTIM){
3113
3114                         tmp_unistim_info = tmp_listinfo->prot_info;
3115
3116                         /* Search by termid if possible, otherwise use ni/it ip + port.. */
3117                         if(pi->termid != 0){
3118                                 if(tmp_unistim_info->termid == pi->termid){
3119                                         /* If the call has ended, then we can reuse it.. */
3120                                         if(tmp_listinfo->call_state == VOIP_COMPLETED || tmp_listinfo->call_state == VOIP_UNKNOWN){
3121                                                 /* Do nothing */
3122                                         } else {
3123                                                 callsinfo = (voip_calls_info_t*)(list->data);
3124                                                 break;
3125                                         }
3126                                 }
3127                         } else {
3128                                 /* If no term id use ips / port to find entry */
3129                                 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)){
3130                                         if(tmp_listinfo->call_state == VOIP_COMPLETED || tmp_listinfo->call_state == VOIP_UNKNOWN){
3131                                                 /* Do nothing previous call */
3132                                         } else {
3133                                                 callsinfo = (voip_calls_info_t*)(list->data);
3134                                                 break;
3135                                         }
3136                                 }
3137                                 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)) {
3138                                         if(tmp_listinfo->call_state == VOIP_COMPLETED || tmp_listinfo->call_state == VOIP_UNKNOWN){
3139                                                 /* Do nothing, it ain't our call.. */
3140                                         } else {
3141                                                 callsinfo = (voip_calls_info_t*)(list->data);
3142                                                 break;
3143                                         }
3144                                 }
3145                         }
3146                 }
3147
3148                 /* Otherwise, go to the next one.. */
3149                 list = g_list_next(list);
3150         }
3151
3152         if(pi->payload_type == 2 || pi->payload_type == 1){
3153
3154                 if(pi->key_state == 1 || pi->hook_state == 1){
3155
3156                         /* If the user hits a button,
3157                            Session will be SETUP */
3158
3159                         /* If new add to list */
3160                         if (callsinfo==NULL){
3161
3162                                 callsinfo = g_malloc0(sizeof(voip_calls_info_t));
3163                                 callsinfo->call_active_state = VOIP_ACTIVE;
3164                                 callsinfo->call_state = VOIP_CALL_SETUP;
3165                                 callsinfo->from_identity=g_strdup_printf("%x",pi->termid);
3166                                 callsinfo->to_identity=g_strdup("UNKNOWN");
3167                                 COPY_ADDRESS(&(callsinfo->initial_speaker),&(pinfo->src));
3168                                 callsinfo->first_frame_num=pinfo->fd->num;
3169                                 callsinfo->selected=FALSE;
3170
3171                                 /* Set this on init of struct so in case the call doesn't complete, we'll have a ref. */
3172                                 /* Otherwise if the call is completed we'll have the open/close streams to ref actual call duration */
3173                                 callsinfo->start_abs=pinfo->fd->abs_ts;
3174                                 callsinfo->start_rel=pinfo->fd->rel_ts;
3175
3176                                 callsinfo->protocol=VOIP_UNISTIM;
3177                                 callsinfo->prot_info=g_malloc(sizeof(unistim_info_t));
3178
3179                                 tmp_unistim_info = callsinfo->prot_info;
3180
3181                                 /* Clear tap struct */
3182                                 tmp_unistim_info->rudp_type = 0;
3183                                 tmp_unistim_info->payload_type = 0;
3184                                 tmp_unistim_info->sequence = pi->sequence;
3185                                 tmp_unistim_info->termid = pi->termid;
3186                                 tmp_unistim_info->key_val = -1;
3187                                 tmp_unistim_info->key_state = -1;
3188                                 tmp_unistim_info->hook_state = -1;
3189                                 tmp_unistim_info->stream_connect = -1;
3190                                 tmp_unistim_info->trans_connect = -1;
3191                                 tmp_unistim_info->set_termid = -1;
3192                                 tmp_unistim_info->string_data = NULL;
3193                                 tmp_unistim_info->key_buffer = NULL;
3194
3195                                 COPY_ADDRESS(&(tmp_unistim_info->it_ip),&(pi->it_ip));
3196                                 COPY_ADDRESS(&(tmp_unistim_info->ni_ip),&(pi->ni_ip));
3197                                 tmp_unistim_info->it_port = pi->it_port;
3198
3199                                 callsinfo->free_prot_info = g_free;
3200                                 callsinfo->npackets = 0;
3201                                 callsinfo->call_num = tapinfo->ncalls++;
3202                                 tapinfo->callsinfo_list = g_list_append(tapinfo->callsinfo_list, callsinfo);
3203
3204                         } else {
3205
3206                                 /* Set up call wide info struct */
3207                                 tmp_unistim_info = callsinfo->prot_info;
3208                                 tmp_unistim_info->sequence = pi->sequence;
3209                         }
3210
3211                         /* Each packet COULD BE OUR LAST!!!! */
3212                         callsinfo->stop_abs = pinfo->fd->abs_ts;
3213                         callsinfo->stop_rel = pinfo->fd->rel_ts;
3214                         callsinfo->last_frame_num=pinfo->fd->num;
3215
3216                         /* This is a valid packet so increment counter */
3217                         ++(callsinfo->npackets);
3218
3219                         /* increment the packets counter of all calls */
3220                         ++(tapinfo->npackets);
3221
3222                         /* Key was depressed.. update key buffer.. */
3223                         if(pi->key_val >= 0 && pi->key_val <= 11){
3224
3225                                 if(tmp_unistim_info->key_buffer != NULL){
3226
3227                                         /* assign to temp variable */
3228                                         g_string_assign(g_tmp,tmp_unistim_info->key_buffer);
3229
3230                                         /* Manipulate the data */
3231                                         if(pi->key_val == 10) {
3232                                                 tmp_unistim_info->key_buffer = g_strdup_printf("%s*",g_tmp->str);
3233                                         } else if(pi->key_val == 11) {
3234                                                 tmp_unistim_info->key_buffer = g_strdup_printf("%s#",g_tmp->str);
3235                                         } else {
3236                                                 tmp_unistim_info->key_buffer = g_strdup_printf("%s%d",g_tmp->str,pi->key_val);
3237                                         }
3238
3239                                 } else {
3240
3241                                         /* Create new string */
3242                                         if(pi->key_val == 10) {
3243                                                 tmp_unistim_info->key_buffer = g_strdup("*");
3244                                         } else if(pi->key_val == 11) {
3245                                                 tmp_unistim_info->key_buffer = g_strdup("#");
3246                                         } else {
3247                                                 tmp_unistim_info->key_buffer = g_strdup_printf("%d",pi->key_val);
3248                                         }
3249
3250                                 }
3251
3252                                 /* Select for non-digit characters */
3253                                 if(pi->key_val == 10) {
3254                                         comment = g_strdup_printf("Key Input Sent: * (%d)", pi->sequence);
3255                                 } else if(pi->key_val == 11) {
3256                                         comment = g_strdup_printf("Key Input Sent: # (%d)", pi->sequence);
3257                                 } else {
3258                                         comment = g_strdup_printf("Key Input Sent: %d (%d)",pi->key_val, pi->sequence);
3259                                 }
3260                         } else if(pi->key_val == 12) {
3261                                 /* Set label and comment for graph */
3262                                 comment = g_strdup_printf("Key Input Sent: UP (%d)", pi->sequence);
3263                         } else if(pi->key_val == 13) {
3264                                 /* Set label and comment for graph */
3265                                 comment = g_strdup_printf("Key Input Sent: DOWN (%d)", pi->sequence);
3266                         } else if(pi->key_val == 14) {
3267                                 /* Set label and comment for graph */
3268                                 comment = g_strdup_printf("Key Input Sent: RIGHT (%d)", pi->sequence);
3269                         } else if(pi->key_val == 15) {
3270                                 if(pi->key_buffer != NULL){
3271                                         /* Get data */
3272                                         g_string_assign(g_tmp,pi->key_buffer);
3273
3274                                         /* Manipulate the data */
3275                                         g_string_truncate(g_tmp,g_tmp->len-1);
3276
3277                                         /* Insert new data */
3278                                         tmp_unistim_info->key_buffer = g_strdup(g_tmp->str);
3279                                 }
3280
3281                                 /* Set label and comment for graph */
3282                                 comment = g_strdup_printf("Key Input Sent: LEFT (%d)", pi->sequence);
3283                         } else if(pi->key_val == 20) {
3284                                 /* User pressed the soft key 0 probably dial */
3285                                 comment = g_strdup_printf("Key Input Sent: S0 (%d)", pi->sequence);
3286                         } else if(pi->key_val == 21) {
3287                                 /* User pressed the soft key 1 */
3288                                 comment = g_strdup_printf("Key Input Sent: S1 (%d)", pi->sequence);
3289                         } else if(pi->key_val == 22) {
3290                                 /* User pressed the soft key 2 */
3291                                 /* On cs2k phones, soft key 2 is backspace. */
3292                                 if(pi->key_buffer != NULL) {
3293
3294                                         /* Get data */
3295                                         g_string_assign(g_tmp,pi->key_buffer);
3296
3297                                         /* Manipulate the data */
3298                                         g_string_truncate(g_tmp,g_tmp->len-1);
3299
3300                                         /* Insert new data */
3301                                         tmp_unistim_info->key_buffer = g_strdup(g_tmp->str);
3302                                 }
3303
3304                                 /* add label and comment */
3305                                 comment = g_strdup_printf("Key Input Sent: S2 (%d)", pi->sequence);
3306                         } else if(pi->key_val == 28) {
3307                                 /* User pressed something */
3308                                 comment = g_strdup_printf("Key Input Sent: Release (%d)", pi->sequence);
3309                         } else if(pi->key_val == 23) {
3310                                 /* User pressed the soft key 3 */
3311                                 /* Cancel on cs2k so clear buffer */
3312                                 /* On mcs its config which will clear the buffer too */
3313                                 tmp_unistim_info->key_buffer = g_strdup("\n");
3314
3315                                 /* User pressed something, set labels*/
3316                                 comment = g_strdup_printf("Key Input Sent: S3 (%d)", pi->sequence);
3317                         } else if(pi->key_val == 27) {
3318                                 /* User pressed something */
3319                                 comment = g_strdup_printf("Key Input Sent: Hold (%d)", pi->sequence);
3320                         } else if(pi->key_val == 29) {
3321                                 /* User pressed something */
3322                                 comment = g_strdup_printf("Key Input Sent: Mute (%d)", pi->sequence);
3323                         } else if(pi->key_val == 30) {
3324                                 /* User pressed something */
3325                                 comment = g_strdup_printf("Key Input Sent: Headset (%d)", pi->sequence);
3326                         } else if(pi->key_val == 31) {
3327                                 /* Handsfree button */
3328                                 comment = g_strdup_printf("Key Input Sent: Handsfree (%d)", pi->sequence);
3329                         } else if(pi->key_val >= 32 && pi->key_val <= 56) {
3330                                 /* Prog. Key X */
3331                                 comment = g_strdup_printf("Key Input Sent: Prog%d (%d)", (pi->key_val & 31), pi->sequence);
3332                         }
3333
3334                         if(pi->key_val != -1) {
3335
3336                                 frame_label = "KEY INPUT";
3337
3338                                 if (comment == NULL)
3339                                         /* Ouch! What do you do!? */
3340                                         /* User pressed something */
3341                                         comment = g_strdup_printf("Key Input Sent: UNKNOWN - %d (%d)", pi->key_val, pi->sequence);
3342
3343                                 /* add to the graph */
3344                                 add_to_graph(tapinfo, pinfo, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3345
3346                                 g_free(comment);
3347                         }
3348
3349                         if(pi->hook_state == 1) {
3350
3351                                 /* Phone is off hook */
3352                                 frame_label = "OFF HOOK";
3353                                 comment = g_strdup_printf("Off Hook (%d)", pi->sequence);
3354
3355                                 /* add to the graph */
3356                                 add_to_graph(tapinfo, pinfo, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3357
3358                                 g_free(comment);
3359                         } else if(pi->hook_state == 0) {
3360
3361                                 /* Phone is on hook */
3362                                 frame_label = "ON HOOK";
3363                                 comment = g_strdup_printf("On Hook (%d)", pi->sequence);
3364
3365                                 /* add to the graph */
3366                                 add_to_graph(tapinfo, pinfo, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3367
3368                                 g_free(comment);
3369                         }
3370                 }
3371
3372                 /* Open stream was sent from server */
3373                 if(pi->stream_connect == 1 && callsinfo != NULL) {
3374
3375                         /* Open stream */
3376                         /* Signifies the start of the call so set start_sec & start_usec */
3377                         callsinfo->start_abs=pinfo->fd->abs_ts;
3378                         callsinfo->start_rel=pinfo->fd->rel_ts;
3379
3380                         /* Local packets too */
3381                         ++(callsinfo->npackets);
3382
3383                         /* increment the packets counter of all calls */
3384                         ++(tapinfo->npackets);
3385
3386                         /* ?? means we're not quite sure if this is accurate. Since Unistim isn't a true
3387                            Call control protocol, we can only guess at the destination by messing with
3388                            key buffers. */
3389                         if(tmp_unistim_info->key_buffer != NULL){
3390                                 callsinfo->to_identity = g_strdup_printf("?? %s",tmp_unistim_info->key_buffer);
3391                         }
3392
3393                         /* change sequence number for ACK detection */
3394                         tmp_unistim_info->sequence = pi->sequence;
3395
3396                         /* State changes too */
3397                         callsinfo->call_active_state = VOIP_ACTIVE;
3398                         callsinfo->call_state = VOIP_IN_CALL;
3399
3400                         /* Add graph data */
3401                         frame_label = "STREAM OPENED";
3402                         comment = g_strdup_printf("Stream Opened (%d)",pi->sequence);
3403
3404                         /* add to the graph */
3405                         add_to_graph(tapinfo, pinfo, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3406
3407                 } else if(pi->stream_connect == 1 && callsinfo == NULL) {
3408
3409                         /* Research indicates some nortel products initiate stream first
3410                          * without keypresses. therefore creating this solely on a keypress is
3411                          * ineffective.
3412                          * Sometimes calls start immediately with open stream.
3413                          */
3414                         callsinfo = g_malloc0(sizeof(voip_calls_info_t));
3415                         callsinfo->call_active_state = VOIP_ACTIVE;
3416                         callsinfo->call_state = VOIP_CALL_SETUP;
3417                         callsinfo->from_identity=g_strdup("UNKNOWN");
3418                         callsinfo->to_identity=g_strdup("UNKNOWN");
3419                         COPY_ADDRESS(&(callsinfo->initial_speaker),&(pinfo->src));
3420                         callsinfo->first_frame_num=pinfo->fd->num;
3421                         callsinfo->selected=FALSE;
3422
3423                         /* Set this on init of struct so in case the call doesn't complete, we'll have a ref. */
3424                         /* Otherwise if the call is completed we'll have the open/close streams to ref actual call duration */
3425                         callsinfo->start_abs=pinfo->fd->abs_ts;
3426                         callsinfo->start_rel=pinfo->fd->rel_ts;
3427
3428                         callsinfo->protocol=VOIP_UNISTIM;
3429                         callsinfo->prot_info=g_malloc(sizeof(unistim_info_t));
3430
3431                         tmp_unistim_info = callsinfo->prot_info;
3432
3433                         /* Clear tap struct */
3434                         tmp_unistim_info->rudp_type = 0;
3435                         tmp_unistim_info->payload_type = 0;
3436                         tmp_unistim_info->sequence = pi->sequence;
3437                         tmp_unistim_info->termid = 0;
3438                         tmp_unistim_info->key_val = -1;
3439                         tmp_unistim_info->key_state = -1;
3440                         tmp_unistim_info->hook_state = -1;
3441                         tmp_unistim_info->stream_connect = -1;
3442                         tmp_unistim_info->trans_connect = -1;
3443                         tmp_unistim_info->set_termid = -1;
3444                         tmp_unistim_info->string_data = NULL;
3445                         tmp_unistim_info->key_buffer = NULL;
3446
3447                         COPY_ADDRESS(&(tmp_unistim_info->it_ip),&(pi->it_ip));
3448                         COPY_ADDRESS(&(tmp_unistim_info->ni_ip),&(pi->ni_ip));
3449                         tmp_unistim_info->it_port = pi->it_port;
3450
3451                         callsinfo->free_prot_info = g_free;
3452                         callsinfo->npackets = 0;
3453                         callsinfo->call_num = tapinfo->ncalls++;
3454                         tapinfo->callsinfo_list = g_list_append(tapinfo->callsinfo_list, callsinfo);
3455
3456                                 /* Open stream */
3457                         /* Signifies the start of the call so set start_sec & start_usec */
3458                         callsinfo->start_abs=pinfo->fd->abs_ts;
3459                         callsinfo->start_rel=pinfo->fd->rel_ts;
3460
3461                         /* Local packets too */
3462                         ++(callsinfo->npackets);
3463
3464                         /* increment the packets counter of all calls */
3465                         ++(tapinfo->npackets);
3466
3467                         /* ?? means we're not quite sure if this is accurate. Since Unistim isn't a true
3468                            Call control protocol, we can only guess at the destination by messing with
3469                            key buffers. */
3470                         if(tmp_unistim_info->key_buffer != NULL){
3471                                 callsinfo->to_identity = g_strdup_printf("?? %s",tmp_unistim_info->key_buffer);
3472                         }
3473
3474                         /* change sequence number for ACK detection */
3475                         tmp_unistim_info->sequence = pi->sequence;
3476
3477                         /* State changes too */
3478                         callsinfo->call_active_state = VOIP_ACTIVE;
3479                         callsinfo->call_state = VOIP_IN_CALL;
3480
3481                         /* Add graph data */
3482                         frame_label = "STREAM OPENED";
3483                         comment = g_strdup_printf("Stream Opened (%d)",pi->sequence);
3484
3485                         /* add to the graph */
3486                         add_to_graph(tapinfo, pinfo, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3487
3488                 } else if(pi->stream_connect == 0 && callsinfo != NULL) {
3489                         /* Close Stream */
3490
3491                         /* Set stop seconds + usec */
3492                         callsinfo->stop_abs = pinfo->fd->abs_ts;
3493                         callsinfo->stop_rel = pinfo->fd->rel_ts;
3494                         callsinfo->last_frame_num=pinfo->fd->num;
3495
3496                         tmp_unistim_info->sequence = pi->sequence;
3497
3498                         if(callsinfo->call_state == VOIP_IN_CALL){
3499                                 callsinfo->call_active_state = VOIP_INACTIVE;
3500                                 callsinfo->call_state = VOIP_COMPLETED;
3501                         } else {
3502                                 callsinfo->call_state = VOIP_UNKNOWN;
3503                                 callsinfo->call_active_state = VOIP_INACTIVE;
3504                         }
3505
3506                         frame_label = "STREAM CLOSED";
3507                         comment = g_strdup_printf("Stream Closed (%d)",pi->sequence);
3508
3509                         /* add to the graph */
3510                         add_to_graph(tapinfo, pinfo, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3511
3512                 } else
3513                         comment = NULL;
3514
3515         } else if(pi->rudp_type == 1 && callsinfo != NULL) {
3516                 /* ACK */
3517                 /* Only show acks for processed seq #s */
3518                 if(tmp_unistim_info->sequence == pi->sequence) {
3519
3520                         frame_label = "ACK";
3521                         comment = g_strdup_printf("ACK for sequence %d",pi->sequence);
3522
3523                         /* add to the graph */
3524                         add_to_graph(tapinfo, pinfo, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3525
3526                 }
3527
3528         } else if(pi->rudp_type == 0 && callsinfo != NULL) {
3529
3530                 /* NAK */
3531                 frame_label = "NAK";
3532                 comment = g_strdup_printf("NAK for sequence %d",pi->sequence);
3533
3534                 /* add to the graph */
3535                 add_to_graph(tapinfo, pinfo, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3536
3537         }
3538
3539         /* free data */
3540         g_free(comment);
3541
3542         tapinfo->redraw = TRUE;
3543
3544         return 1;
3545 }
3546
3547 /****************************************************************************/
3548 /* TAP INTERFACE */
3549 /****************************************************************************/
3550 static gboolean have_unistim_tap_listener=FALSE;
3551 /****************************************************************************/
3552 void
3553 unistim_calls_init_tap(void){
3554
3555         GString *error_string;
3556
3557         if(have_unistim_tap_listener==FALSE) {
3558
3559                 error_string = register_tap_listener("unistim", &(the_tapinfo_struct.unistim_dummy),
3560                         NULL,
3561                         0,
3562                         voip_calls_dlg_reset,
3563                         unistim_calls_packet,
3564                         voip_calls_dlg_draw
3565                         );
3566
3567                 if (error_string != NULL) {
3568                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3569                                       "%s", error_string->str);
3570                         g_string_free(error_string, TRUE);
3571                         exit(1);
3572                 }
3573
3574                 have_unistim_tap_listener=TRUE;
3575         }
3576 }
3577
3578 /****************************************************************************/
3579 void
3580 remove_tap_listener_unistim_calls(void)
3581 {
3582         protect_thread_critical_region();
3583         remove_tap_listener(&(the_tapinfo_struct.unistim_dummy));
3584         unprotect_thread_critical_region();
3585
3586         have_unistim_tap_listener=FALSE;
3587 }
3588
3589 /****************************************************************************/
3590 /* ***************************TAP for SKINNY **********************************/
3591 /****************************************************************************/
3592
3593 /* Telecaster to tap-voip call state mapping */
3594 static const voip_call_state skinny_tap_voip_state[] = {
3595         VOIP_NO_STATE,
3596         VOIP_CALL_SETUP,
3597         VOIP_COMPLETED,
3598         VOIP_RINGING,
3599         VOIP_RINGING,
3600         VOIP_IN_CALL,
3601         VOIP_REJECTED,
3602         VOIP_REJECTED,
3603         VOIP_IN_CALL,
3604         VOIP_IN_CALL,
3605         VOIP_COMPLETED,
3606         VOIP_COMPLETED,
3607         VOIP_CALL_SETUP,
3608         VOIP_UNKNOWN,
3609         VOIP_REJECTED
3610 };
3611
3612 static int
3613 skinny_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *skinny_info)
3614 {
3615         voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
3616         GList* list;
3617         voip_calls_info_t *callsinfo = NULL;
3618         address* phone;
3619         const skinny_info_t *si = skinny_info;
3620         skinny_calls_info_t *tmp_skinnyinfo;
3621         gchar *comment;
3622
3623         if (si == NULL || (si->callId == 0 && si->passThruId == 0))
3624                 return 0;
3625         /* check whether we already have this context in the list */
3626         list = g_list_first(tapinfo->callsinfo_list);
3627         while (list)
3628         {
3629                 voip_calls_info_t* tmp_listinfo = list->data;
3630                 if (tmp_listinfo->protocol == VOIP_SKINNY){
3631                         tmp_skinnyinfo = tmp_listinfo->prot_info;
3632                         if (tmp_skinnyinfo->callId == si->callId ||
3633                             tmp_skinnyinfo->callId == si->passThruId){
3634                                 callsinfo = (voip_calls_info_t*)(list->data);
3635                                 break;
3636                         }
3637                 }
3638                 list = g_list_next (list);
3639         }
3640
3641         if (si->messId >= 256)
3642                 phone = &(pinfo->dst);
3643         else
3644                 phone = &(pinfo->src);
3645
3646         if (callsinfo==NULL){
3647                 callsinfo = g_malloc0(sizeof(voip_calls_info_t));
3648                 callsinfo->call_state = VOIP_NO_STATE;
3649                 callsinfo->call_active_state = VOIP_ACTIVE;
3650                 /* callsinfo->from_identity = g_strdup_printf("%s : %.8x", "Skinny", 1); */
3651                 callsinfo->from_identity = g_strdup("");
3652                 callsinfo->to_identity = g_strdup("");
3653                 callsinfo->prot_info = g_malloc(sizeof(skinny_calls_info_t));
3654                 callsinfo->free_prot_info = g_free;
3655                 tmp_skinnyinfo = callsinfo->prot_info;
3656                 tmp_skinnyinfo->callId = si->callId ? si->callId : si->passThruId;
3657                 callsinfo->npackets = 1;
3658                 callsinfo->first_frame_num=pinfo->fd->num;
3659                 callsinfo->last_frame_num=pinfo->fd->num;
3660
3661                 COPY_ADDRESS(&(callsinfo->initial_speaker), phone);
3662
3663                 callsinfo->protocol = VOIP_SKINNY;
3664                 callsinfo->call_num = tapinfo->ncalls++;
3665                 callsinfo->start_abs = pinfo->fd->abs_ts;
3666                 callsinfo->start_rel = pinfo->fd->rel_ts;
3667                 callsinfo->stop_abs = pinfo->fd->abs_ts;
3668                 callsinfo->stop_rel = pinfo->fd->rel_ts;
3669
3670                 callsinfo->selected = FALSE;
3671                 tapinfo->callsinfo_list = g_list_append(tapinfo->callsinfo_list, callsinfo);
3672         } else {
3673                 if (si->callingParty) {
3674                         g_free(callsinfo->from_identity);
3675                         callsinfo->from_identity = g_strdup(si->callingParty);
3676                 }
3677                 if (si->calledParty) {
3678                         g_free(callsinfo->to_identity);
3679                         callsinfo->to_identity =  g_strdup(si->calledParty);
3680                 }
3681                 if ((si->callState > 0) && (si->callState < (sizeof(skinny_tap_voip_state)/sizeof(skinny_tap_voip_state[0]))))
3682                         callsinfo->call_state = skinny_tap_voip_state[si->callState];
3683
3684                 callsinfo->stop_abs = pinfo->fd->abs_ts;
3685                 callsinfo->stop_rel = pinfo->fd->rel_ts;
3686                 callsinfo->last_frame_num=pinfo->fd->num;
3687                 ++(callsinfo->npackets);
3688         }
3689
3690         if (si->callId) {
3691                 if (si->passThruId)
3692                         comment = g_strdup_printf("CallId = %u, PTId = %u", si->callId, si->passThruId);
3693                 else
3694                         comment = g_strdup_printf("CallId = %u, LineId = %u", si->callId, si->lineId);
3695         } else {
3696                 if (si->passThruId)
3697                         comment = g_strdup_printf("PTId = %u", si->passThruId);
3698                 else
3699                         comment = NULL;
3700         }
3701
3702         add_to_graph(tapinfo, pinfo, si->messageName, comment,
3703                                  callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3704         g_free(comment);
3705
3706         return 1;
3707 }
3708
3709
3710 /****************************************************************************/
3711 /* TAP INTERFACE */
3712 /****************************************************************************/
3713 static gboolean have_skinny_tap_listener=FALSE;
3714 /****************************************************************************/
3715 void
3716 skinny_calls_init_tap(void)
3717 {
3718         GString *error_string;
3719
3720         if(have_skinny_tap_listener==FALSE)
3721         {
3722                 /*
3723                  * Don't register the tap listener if we have it already.
3724                  * We set TL_REQUIRES_PROTO_TREE to force a non-null "tree"
3725                  * in the SKINNY dissector; otherwise, the dissector
3726                  * doesn't fill in the info passed to the tap's packet
3727                  * routine.
3728                  */
3729                 error_string = register_tap_listener("skinny", 
3730                         &(the_tapinfo_struct.skinny_dummy), 
3731                         NULL,
3732                         TL_REQUIRES_PROTO_TREE,
3733                         voip_calls_dlg_reset,
3734                         skinny_calls_packet,
3735                         voip_calls_dlg_draw
3736                         );
3737                 if (error_string != NULL) {
3738                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3739                                       "%s", error_string->str);
3740                         g_string_free(error_string, TRUE);
3741                         exit(1);
3742                 }
3743                 have_skinny_tap_listener=TRUE;
3744         }
3745 }
3746
3747 /****************************************************************************/
3748 void
3749 remove_tap_listener_skinny_calls(void)
3750 {
3751         protect_thread_critical_region();
3752         remove_tap_listener(&(the_tapinfo_struct.skinny_dummy));
3753         unprotect_thread_critical_region();
3754
3755         have_skinny_tap_listener=FALSE;
3756 }
3757
3758 /****************************************************************************/
3759 /* ***************************TAP for IAX2 **********************************/
3760 /****************************************************************************/
3761
3762 /* IAX2 to tap-voip call state mapping */
3763 static const voip_call_state tap_iax_voip_state[] = {
3764         VOIP_NO_STATE,
3765         VOIP_CALL_SETUP, /*NEW*/
3766         VOIP_NO_STATE,
3767         VOIP_NO_STATE,
3768         VOIP_COMPLETED,  /*HANGUP*/
3769         VOIP_REJECTED,   /*REJECT*/
3770         VOIP_RINGING,   /*ACCEPT*/
3771         VOIP_NO_STATE,
3772         VOIP_NO_STATE,
3773         VOIP_NO_STATE,
3774         VOIP_NO_STATE,
3775         VOIP_NO_STATE,
3776         VOIP_NO_STATE,
3777         VOIP_NO_STATE,
3778         VOIP_NO_STATE,
3779         VOIP_NO_STATE,
3780         VOIP_NO_STATE,
3781         VOIP_NO_STATE,
3782         VOIP_NO_STATE,
3783         VOIP_NO_STATE,
3784         VOIP_NO_STATE,
3785         VOIP_CALL_SETUP, /*DIAL*/
3786         VOIP_NO_STATE,
3787         VOIP_NO_STATE,
3788         VOIP_NO_STATE,
3789         VOIP_NO_STATE,
3790         VOIP_NO_STATE,
3791         VOIP_NO_STATE,
3792         VOIP_NO_STATE,
3793         VOIP_NO_STATE,
3794         VOIP_NO_STATE,
3795         VOIP_NO_STATE,
3796         VOIP_NO_STATE,
3797         VOIP_NO_STATE,
3798         VOIP_NO_STATE,
3799         VOIP_NO_STATE,
3800         VOIP_NO_STATE,
3801         VOIP_NO_STATE
3802 };
3803
3804 static void free_iax2_info(gpointer p) {
3805         iax2_info_t *ii = p;
3806
3807         g_free(ii);
3808 }
3809
3810
3811 /****************************************************************************/
3812 /* whenever a IAX2 packet is seen by the tap listener */
3813 static int
3814 iax2_calls_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *iax2_info)
3815 {
3816         voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
3817         GList* list;
3818         voip_calls_info_t *callsinfo = NULL;
3819         address* phone;
3820         const iax2_info_t *ii = iax2_info;
3821         iax2_info_t *tmp_iax2info;
3822         gchar * comment;
3823
3824         if (ii == NULL || ii->ptype != IAX2_FULL_PACKET || (ii->scallno == 0 && ii->dcallno == 0))
3825                 return 0;
3826         /* check whether we already have this context in the list */
3827         list = g_list_first(tapinfo->callsinfo_list);
3828         while (list)
3829         {
3830                 voip_calls_info_t* tmp_listinfo = list->data;
3831                 if (tmp_listinfo->protocol == VOIP_IAX2){
3832                         tmp_iax2info = tmp_listinfo->prot_info;
3833                         if (tmp_iax2info->scallno == ii->scallno ||
3834                             tmp_iax2info->scallno == ii->dcallno){
3835                                 callsinfo = (voip_calls_info_t*)(list->data);
3836                                 break;
3837                         }
3838                 }
3839                 list = g_list_next (list);
3840         }
3841         phone = &(pinfo->src);
3842
3843
3844         if (callsinfo==NULL){
3845                 /* We only care about real calls, i.e., no registration stuff */
3846                 if (ii->ftype != AST_FRAME_IAX ||  ii->csub != IAX_COMMAND_NEW)
3847                         return 0;
3848                 callsinfo = g_malloc0(sizeof(voip_calls_info_t));
3849                 callsinfo->call_state = VOIP_NO_STATE;
3850                 callsinfo->call_active_state = VOIP_ACTIVE;
3851                 callsinfo->prot_info=g_malloc(sizeof(iax2_info_t));
3852                 callsinfo->free_prot_info = free_iax2_info;
3853                 tmp_iax2info = callsinfo->prot_info;
3854
3855                 tmp_iax2info->scallno = ii->scallno;
3856                 if (tmp_iax2info->scallno == 0) tmp_iax2info->scallno = ii->dcallno;
3857                 tmp_iax2info->callState = tap_iax_voip_state[ii->callState];
3858
3859                 callsinfo->npackets = 1;
3860                 callsinfo->first_frame_num=pinfo->fd->num;
3861                 callsinfo->last_frame_num=pinfo->fd->num;
3862
3863                 COPY_ADDRESS(&(callsinfo->initial_speaker), phone);
3864                 callsinfo->from_identity = g_strdup(ii->callingParty);
3865                 callsinfo->to_identity =  g_strdup(ii->calledParty);
3866
3867                 callsinfo->protocol = VOIP_IAX2;
3868                 callsinfo->call_num = tapinfo->ncalls++;
3869                 callsinfo->start_abs=pinfo->fd->abs_ts;
3870                 callsinfo->start_rel=pinfo->fd->rel_ts;
3871                 callsinfo->stop_abs = pinfo->fd->abs_ts;
3872                 callsinfo->stop_rel = pinfo->fd->rel_ts;
3873
3874                 callsinfo->selected = FALSE;
3875                 tapinfo->callsinfo_list = g_list_append(tapinfo->callsinfo_list, callsinfo);
3876
3877         } else {
3878                 if ((ii->callState > 0) && (ii->callState < (sizeof(tap_iax_voip_state)/sizeof(tap_iax_voip_state[0]))))
3879                         callsinfo->call_state = tap_iax_voip_state[ii->callState];
3880
3881                 callsinfo->stop_abs = pinfo->fd->abs_ts;
3882                 callsinfo->stop_rel = pinfo->fd->rel_ts;
3883                 callsinfo->last_frame_num=pinfo->fd->num;
3884                 ++(callsinfo->npackets);
3885         }
3886
3887         comment = "";
3888
3889         add_to_graph(tapinfo, pinfo, ii->messageName, comment,
3890                                  callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3891
3892         return 1;
3893
3894 }
3895
3896
3897 /****************************************************************************/
3898 /* TAP INTERFACE */
3899 /****************************************************************************/
3900 static gboolean have_iax2_tap_listener=FALSE;
3901 /****************************************************************************/
3902 void
3903 iax2_calls_init_tap(void)
3904 {
3905         GString *error_string;
3906
3907         if(have_iax2_tap_listener==FALSE)
3908         {
3909                 /*
3910                  * Don't register the tap listener if we have it already.
3911                  * We set TL_REQUIRES_PROTO_TREE to force a non-null "tree"
3912                  * in the IAX2 dissector; otherwise, the dissector
3913                  * doesn't fill in the info passed to the tap's packet
3914                  * routine.
3915                  * XXX - that appears to be true of the MGCP and SKINNY
3916                  * dissectors, but, unless I've missed something, it doesn't
3917                  * appear to be true of the IAX2 dissector.
3918                  */
3919                 error_string = register_tap_listener("IAX2", 
3920                         &(the_tapinfo_struct.iax2_dummy), 
3921                         NULL,
3922                         TL_REQUIRES_PROTO_TREE,
3923                         voip_calls_dlg_reset,
3924                         iax2_calls_packet,
3925                         voip_calls_dlg_draw
3926                         );
3927                 if (error_string != NULL) {
3928                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s",
3929                                       error_string->str);
3930                         g_string_free(error_string, TRUE);
3931                         exit(1);
3932                 }
3933                 have_iax2_tap_listener=TRUE;
3934         }
3935 }
3936
3937 /****************************************************************************/
3938 void
3939 remove_tap_listener_iax2_calls(void)
3940 {
3941         protect_thread_critical_region();
3942         remove_tap_listener(&(the_tapinfo_struct.iax2_dummy));
3943         unprotect_thread_critical_region();
3944
3945         have_iax2_tap_listener=FALSE;
3946 }
3947
3948 /****************************************************************************/
3949 /* ***************************TAP for OTHER PROTOCOL **********************************/
3950 /****************************************************************************/
3951
3952 static int
3953 VoIPcalls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *VoIPinfo)
3954 {
3955         voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
3956         voip_calls_info_t *callsinfo = NULL;
3957         voip_calls_info_t *tmp_listinfo;
3958         GList *list = NULL;
3959         const voip_packet_info_t *pi = VoIPinfo;
3960
3961         if (pi->call_id)
3962                 list = g_list_first(tapinfo->callsinfo_list);
3963         while (list) {
3964                 tmp_listinfo = list->data;
3965                 if ( tmp_listinfo->protocol == VOIP_COMMON ) {
3966                         if (!strcmp(pi->call_id, tmp_listinfo->call_id)) {
3967                                 callsinfo = (voip_calls_info_t*)(list->data);
3968                                 break;
3969                         }
3970                 }
3971                 list = g_list_next(list);
3972         }
3973
3974         if (callsinfo == NULL) {
3975                 callsinfo = g_malloc0(sizeof(voip_calls_info_t));
3976                 callsinfo->call_active_state = pi->call_active_state;
3977                 callsinfo->call_state = pi->call_state;
3978                 callsinfo->call_id=g_strdup((pi->call_id)?pi->call_id:"");
3979                 callsinfo->from_identity = g_strdup((pi->from_identity)?pi->from_identity:"");
3980                 callsinfo->to_identity = g_strdup((pi->to_identity)?pi->to_identity:"");
3981                 COPY_ADDRESS(&(callsinfo->initial_speaker),&(pinfo->src));
3982                 callsinfo->selected=FALSE;
3983                 callsinfo->first_frame_num=pinfo->fd->num;
3984                 callsinfo->start_abs=pinfo->fd->abs_ts;
3985                 callsinfo->start_rel=pinfo->fd->rel_ts;
3986                 callsinfo->protocol=VOIP_COMMON;
3987                 callsinfo->protocol_name=g_strdup((pi->protocol_name)?pi->protocol_name:"");
3988                 callsinfo->call_comment=g_strdup((pi->call_comment)?pi->call_comment:"");
3989                 callsinfo->prot_info=NULL;
3990                 callsinfo->free_prot_info = NULL;
3991
3992                 callsinfo->call_num = tapinfo->ncalls++;
3993                 callsinfo->npackets = 0;
3994
3995                 tapinfo->callsinfo_list = g_list_append(tapinfo->callsinfo_list, callsinfo);
3996         }
3997
3998         if (callsinfo != NULL) {
3999                 callsinfo->call_active_state = pi->call_active_state;
4000                 if ((callsinfo->call_state != VOIP_COMPLETED) && (pi->call_state == VOIP_COMPLETED))
4001                         tapinfo->completed_calls++;
4002         if (pi->call_state != VOIP_NO_STATE)
4003                         callsinfo->call_state = pi->call_state;
4004                 if (pi->call_comment) {
4005                         g_free(callsinfo->call_comment);
4006                         callsinfo->call_comment=g_strdup(pi->call_comment);
4007                 }
4008                 callsinfo->stop_abs = pinfo->fd->abs_ts;
4009                 callsinfo->stop_rel = pinfo->fd->rel_ts;
4010                 callsinfo->last_frame_num=pinfo->fd->num;
4011                 ++(callsinfo->npackets);
4012                 ++(tapinfo->npackets);
4013         }
4014
4015         /* add to the graph */
4016         add_to_graph(tapinfo, pinfo, (pi->frame_label)?pi->frame_label:"VoIP msg", pi->frame_comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
4017
4018         tapinfo->redraw = TRUE;
4019
4020         return 1;
4021 }
4022 /****************************************************************************/
4023 static gboolean have_voip_tap_listener=FALSE;
4024
4025 void
4026 VoIPcalls_init_tap(void)
4027 {
4028         GString *error_string;
4029
4030         if(have_voip_tap_listener==FALSE)
4031         {
4032                 error_string = register_tap_listener("voip", &(the_tapinfo_struct.voip_dummy),
4033                         NULL,
4034                         0,
4035                         voip_calls_dlg_reset,
4036                         VoIPcalls_packet,
4037                         voip_calls_dlg_draw
4038                         );
4039
4040                 if (error_string != NULL) {
4041                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4042                                       "%s", error_string->str);
4043                         g_string_free(error_string, TRUE);
4044                         exit(1);
4045                 }
4046                 have_voip_tap_listener=TRUE;
4047         }
4048 }
4049 /****************************************************************************/
4050 void
4051 remove_tap_listener_voip_calls(void)
4052 {
4053         protect_thread_critical_region();
4054         remove_tap_listener(&(the_tapinfo_struct.voip_dummy));
4055         unprotect_thread_critical_region();
4056
4057         have_voip_tap_listener=FALSE;
4058 }
4059
4060
4061 /****************************************************************************/
4062 /* ***************************TAP for OTHER PROTOCOL **********************************/
4063 /****************************************************************************/
4064
4065 /****************************************************************************/
4066 /* whenever a prot_ packet is seen by the tap listener */
4067 /*
4068 static int
4069 prot_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *prot_info _U_)
4070 {
4071         voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
4072         if (callsinfo!=NULL){
4073                 callsinfo->stop_abs = pinfo->fd->abs_ts;
4074                 callsinfo->stop_rel = pinfo->fd->rel_ts;
4075                 callsinfo->last_frame_num=pinfo->fd->num;
4076                 ++(callsinfo->npackets);
4077                 ++(tapinfo->npackets);
4078         }
4079
4080         tapinfo->redraw = TRUE;
4081
4082         return 1;
4083 }
4084 */
4085 /****************************************************************************/
4086 /*
4087 static gboolean have_prot__tap_listener=FALSE;
4088
4089 void
4090 prot_calls_init_tap(void)
4091 {
4092         GString *error_string;
4093
4094         if(have_prot__tap_listener==FALSE)
4095         {
4096                 error_string = register_tap_listener("prot_", &(the_tapinfo_struct.prot__dummy),
4097                         NULL,
4098                         0,
4099                         voip_calls_dlg_reset,
4100                         prot__calls_packet,
4101                         voip_calls_dlg_draw
4102                         );
4103
4104                 if (error_string != NULL) {
4105                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4106                                       "%s", error_string->str);
4107                         g_string_free(error_string, TRUE);
4108                         exit(1);
4109                 }
4110                 have_prot__tap_listener=TRUE;
4111         }
4112 }
4113 */
4114 /****************************************************************************/
4115 /*
4116 void
4117 remove_tap_listener_prot__calls(void)
4118 {
4119         protect_thread_critical_region();
4120         remove_tap_listener(&(the_tapinfo_struct.prot__dummy));
4121         unprotect_thread_critical_region();
4122
4123         have_prot__tap_listener=FALSE;
4124 }
4125 */