431a74b0d358343f987c431aad5cd768446cff72
[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
40 #include <string.h>
41
42 #include "graph_analysis.h"
43 #include "voip_calls.h"
44 #include "voip_calls_dlg.h"
45
46 #include "main.h"
47 #include "globals.h"
48
49 #include <epan/tap.h>
50 #include <epan/dissectors/packet-sip.h>
51 #include <epan/dissectors/packet-mtp3.h>
52 #include <epan/dissectors/packet-isup.h>
53 #include <epan/dissectors/packet-h225.h>
54 #include <epan/dissectors/packet-h245.h>
55 #include <epan/dissectors/packet-q931.h>
56 #include <epan/dissectors/packet-sdp.h>
57 #include <plugins/mgcp/packet-mgcp.h>
58 #include <epan/dissectors/packet-actrace.h>
59 #include <epan/dissectors/packet-rtp.h>
60 #include <epan/dissectors/packet-rtp-events.h>
61 #include <epan/dissectors/packet-t38.h>
62 #include <epan/conversation.h>
63 #include <epan/rtp_pt.h>
64
65 #include "alert_box.h"
66 #include "simple_dialog.h"
67
68 #ifdef HAVE_LIBPORTAUDIO
69 #if GTK_MAJOR_VERSION >= 2
70 #include "rtp_player.h"
71 #endif /* GTK_MAJOR_VERSION >= 2 */
72 #endif /* HAVE_LIBPORTAUDIO */
73
74 const char *voip_call_state_name[7]={
75         "CALL SETUP",
76         "RINGING",
77         "IN CALL",
78         "CANCELLED",
79         "COMPLETED",
80         "REJECTED",
81         "UNKNOWN"
82         };
83
84 /* defines whether we can consider the call active */
85 const char *voip_protocol_name[7]={
86         "SIP",
87         "ISUP",
88         "H.323",
89         "MGCP",
90         "AC_ISDN",
91         "AC_CAS",
92         "T.38"
93         };
94
95 typedef struct {
96         gchar *frame_label;
97         gchar *comment;
98 } graph_str;
99
100 #define H245_MAX 6
101
102 typedef struct {
103         guint32 frame_num;
104         gint8 labels_count;
105         graph_str labels[H245_MAX];
106 } h245_labels_t;
107
108 static h245_labels_t h245_labels;
109
110 /****************************************************************************/
111 /* the one and only global voip_calls_tapinfo_t structure */
112 static voip_calls_tapinfo_t the_tapinfo_struct =
113         {0, NULL, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
114
115 /* the one and only global voip_rtp_tapinfo_t structure */
116 static voip_rtp_tapinfo_t the_tapinfo_rtp_struct =
117         {0, NULL, 0, 0};
118
119 /****************************************************************************/
120 /* when there is a [re]reading of packet's */
121 void voip_calls_reset(voip_calls_tapinfo_t *tapinfo)
122 {
123         voip_calls_info_t *strinfo;
124         sip_calls_info_t *tmp_sipinfo;
125         h323_calls_info_t *tmp_h323info;
126         h245_address_t *h245_add;
127
128         graph_analysis_item_t *graph_item;
129
130         GList* list;
131         GList* list2;
132
133 #ifdef HAVE_LIBPORTAUDIO
134 #if GTK_MAJOR_VERSION >= 2
135         /* reset the RTP player */
136         reset_rtp_player();
137 #endif
138 #endif
139
140         /* free the data items first */
141         list = g_list_first(tapinfo->strinfo_list);
142         while (list)
143         {
144                 strinfo = list->data;
145                 g_free(strinfo->from_identity);
146                 g_free(strinfo->to_identity);
147                 g_free((void *)(strinfo->initial_speaker.data));
148                 if (strinfo->protocol == VOIP_SIP){
149                         tmp_sipinfo = strinfo->prot_info;
150                         g_free(tmp_sipinfo->call_identifier);
151                 }
152                 if (strinfo->protocol == VOIP_H323){
153                         tmp_h323info = strinfo->prot_info;
154                         g_free(tmp_h323info->guid);
155                         /* free the H245 list address */
156                         list2 = g_list_first(tmp_h323info->h245_list);
157                         while (list2)
158                         {
159                                 h245_add=list2->data;
160                                 g_free((void *)h245_add->h245_address.data);
161                                 g_free(list2->data);
162                                 list2 = g_list_next(list2);
163                         }
164                         g_list_free(tmp_h323info->h245_list);
165                         tmp_h323info->h245_list = NULL;
166                 }
167                 g_free(strinfo->prot_info);
168
169                 g_free(list->data);
170                 list = g_list_next(list);
171         }
172         g_list_free(tapinfo->strinfo_list);
173         tapinfo->strinfo_list = NULL;
174         tapinfo->ncalls = 0;
175         tapinfo->npackets = 0;
176         tapinfo->start_packets = 0;
177         tapinfo->completed_calls = 0;
178         tapinfo->rejected_calls = 0;
179
180         /* free the graph data items first */
181         list = g_list_first(tapinfo->graph_analysis->list);
182         while (list)
183         {
184                 graph_item = list->data;
185                 g_free(graph_item->frame_label);
186                 g_free(graph_item->comment);
187                 g_free((void *)graph_item->src_addr.data);
188                 g_free((void *)graph_item->dst_addr.data);
189                 g_free(list->data);
190                 list = g_list_next(list);
191         }
192         g_list_free(tapinfo->graph_analysis->list);
193         tapinfo->graph_analysis->nconv = 0;
194         tapinfo->graph_analysis->list = NULL;
195
196         ++(tapinfo->launch_count);
197
198         return;
199 }
200
201 /****************************************************************************/
202 void graph_analysis_data_init(void){
203         the_tapinfo_struct.graph_analysis = g_malloc(sizeof(graph_analysis_info_t));
204         the_tapinfo_struct.graph_analysis->nconv = 0;
205         the_tapinfo_struct.graph_analysis->list = NULL;
206 }
207
208 /****************************************************************************/
209 /* Add a new item into the graph */
210 static int add_to_graph(voip_calls_tapinfo_t *tapinfo _U_, packet_info *pinfo, const gchar *frame_label, gchar *comment, guint16 call_num, address *src_addr, address *dst_addr, guint16 line_style)
211 {
212         graph_analysis_item_t *gai;
213
214         gai = g_malloc(sizeof(graph_analysis_item_t));
215         gai->frame_num = pinfo->fd->num;
216         gai->time= nstime_to_sec(&pinfo->fd->rel_ts);
217         COPY_ADDRESS(&(gai->src_addr),src_addr);
218         COPY_ADDRESS(&(gai->dst_addr),dst_addr);
219
220         gai->port_src=pinfo->srcport;
221         gai->port_dst=pinfo->destport;
222         if (frame_label != NULL)
223                 gai->frame_label = g_strdup(frame_label);
224         else
225                 gai->frame_label = g_strdup("");
226
227         if (comment != NULL)
228                 gai->comment = g_strdup(comment);
229         else
230                 gai->comment = g_strdup("");
231         gai->conv_num=call_num;
232         gai->line_style=line_style;
233         gai->display=FALSE;
234
235         tapinfo->graph_analysis->list = g_list_append(tapinfo->graph_analysis->list, gai);
236
237         return 1;
238
239 }
240
241 /****************************************************************************/
242 /* Append str to frame_label and comment in a graph item */
243 /* return 0 if the frame_num is not in the graph list */
244 static int append_to_frame_graph(voip_calls_tapinfo_t *tapinfo _U_, guint32 frame_num, const gchar *new_frame_label, const gchar *new_comment)
245 {
246         graph_analysis_item_t *gai;
247         GList* list;
248         gchar *tmp_str = NULL;
249         gchar *tmp_str2 = NULL;
250
251         list = g_list_first(tapinfo->graph_analysis->list);
252         while (list)
253         {
254                 gai = list->data;
255                 if (gai->frame_num == frame_num){
256                         tmp_str = gai->frame_label;
257                         tmp_str2 = gai->comment;
258
259                         if (new_frame_label != NULL){
260                                 gai->frame_label = g_strdup_printf("%s %s", gai->frame_label, new_frame_label);
261                                 g_free(tmp_str);
262                         }
263
264
265                         if (new_comment != NULL){
266                                 gai->comment = g_strdup_printf("%s %s", gai->comment, new_comment);
267                                 g_free(tmp_str2);
268                         }
269                         break;
270                 }
271                 list = g_list_next (list);
272         }
273         if (tmp_str == NULL) return 0;          /* it is not in the list */
274         return 1;
275
276 }
277
278 /****************************************************************************/
279 /* Change the frame_label and comment in a graph item if not NULL*/
280 /* return 0 if the frame_num is not in the graph list */
281 static int change_frame_graph(voip_calls_tapinfo_t *tapinfo _U_, guint32 frame_num, const gchar *new_frame_label, const gchar *new_comment)
282 {
283         graph_analysis_item_t *gai;
284         GList* list;
285         gchar *tmp_str = NULL;
286         gchar *tmp_str2 = NULL;
287
288         list = g_list_first(tapinfo->graph_analysis->list);
289         while (list)
290         {
291                 gai = list->data;
292                 if (gai->frame_num == frame_num){
293                         tmp_str = gai->frame_label;
294                         tmp_str2 = gai->comment;
295
296                         if (new_frame_label != NULL){
297                                 gai->frame_label = g_strdup(new_frame_label);
298                                 g_free(tmp_str);
299                         }
300
301                         if (new_comment != NULL){
302                                 gai->comment = g_strdup(new_comment);
303                                 g_free(tmp_str2);
304                         }
305                         break;
306                 }
307                 list = g_list_next (list);
308         }
309         if (tmp_str == NULL) return 0;          /* it is not in the list */
310         return 1;
311
312 }
313
314 /****************************************************************************/
315 /* Change all the graph items with call_num to new_call_num */
316 static guint change_call_num_graph(voip_calls_tapinfo_t *tapinfo _U_, guint16 call_num, guint16 new_call_num)
317 {
318         graph_analysis_item_t *gai;
319         GList* list;
320         guint items_changed;
321
322         items_changed = 0;
323         list = g_list_first(tapinfo->graph_analysis->list);
324         while (list)
325         {
326                 gai = list->data;
327                 if (gai->conv_num == call_num){
328                         gai->conv_num = new_call_num;
329                         items_changed++;
330                 }
331                 list = g_list_next (list);
332         }
333         return items_changed;
334 }
335
336
337
338
339 /****************************************************************************/
340 /* Insert the item in the graph list */
341 void insert_to_graph(voip_calls_tapinfo_t *tapinfo _U_, packet_info *pinfo, const gchar *frame_label, gchar *comment, guint16 call_num, address *src_addr, address *dst_addr, guint16 line_style, double time, guint32 frame_num)
342 {
343         graph_analysis_item_t *gai, *new_gai;
344         GList* list;
345         guint item_num;
346         gboolean inserted;
347
348         new_gai = g_malloc(sizeof(graph_analysis_item_t));
349         new_gai->frame_num = frame_num;
350         new_gai->time= time;
351         COPY_ADDRESS(&(new_gai->src_addr),src_addr);
352         COPY_ADDRESS(&(new_gai->dst_addr),dst_addr);
353
354         new_gai->port_src=pinfo->srcport;
355         new_gai->port_dst=pinfo->destport;
356         if (frame_label != NULL)
357                 new_gai->frame_label = g_strdup(frame_label);
358         else
359                 new_gai->frame_label = g_strdup("");
360
361         if (comment != NULL)
362                 new_gai->comment = g_strdup(comment);
363         else
364                 new_gai->comment = g_strdup("");
365         new_gai->conv_num=call_num;
366         new_gai->line_style=line_style;
367         new_gai->display=FALSE;
368
369         item_num = 0; 
370         inserted = FALSE;
371         list = g_list_first(tapinfo->graph_analysis->list);
372         while (list)
373         {
374                 gai = list->data;
375                 if (gai->frame_num > frame_num){
376                         the_tapinfo_struct.graph_analysis->list = g_list_insert(the_tapinfo_struct.graph_analysis->list, new_gai, item_num);
377                         inserted = TRUE;
378                         break;
379                 }
380                 list = g_list_next (list);
381                 item_num++;
382         }
383
384         if ( !inserted) tapinfo->graph_analysis->list = g_list_append(tapinfo->graph_analysis->list, new_gai);
385 }
386
387 /****************************************************************************/
388 /* ***************************TAP for RTP Events*****************************/
389 /****************************************************************************/
390
391 static guint32 rtp_evt_frame_num = 0;
392 static guint8 rtp_evt = 0;
393 static gboolean rtp_evt_end = FALSE;
394 /*static guint32 rtp_evt_setup_frame_num = 0;*/
395
396 /****************************************************************************/
397 /* whenever a rtp event packet is seen by the tap listener */
398 static int 
399 rtp_event_packet(void *ptr _U_, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *rtp_event_info)
400 {
401         const struct _rtp_event_info *pi = rtp_event_info;
402
403         /* do not consider RTP events packets without a setup frame */
404         if (pi->info_setup_frame_num == 0){
405                 return 0;
406         }
407
408         rtp_evt_frame_num = pinfo->fd->num;
409         rtp_evt = pi->info_rtp_evt;
410         rtp_evt_end = pi->info_end;
411
412         return 0;
413 }
414
415 /****************************************************************************/
416 static gboolean have_rtp_event_tap_listener=FALSE;
417
418 void
419 rtp_event_init_tap(void)
420 {
421         GString *error_string;
422
423
424         if(have_rtp_event_tap_listener==FALSE)
425         {
426                 error_string = register_tap_listener("rtpevent", &(the_tapinfo_rtp_struct.rtp_event_dummy),
427                         NULL,
428                         NULL,
429                         rtp_event_packet,
430                         NULL
431                         );
432                         
433                 if (error_string != NULL) {
434                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
435                                       error_string->str);
436                         g_string_free(error_string, TRUE);
437                         exit(1);
438                 }
439                 have_rtp_event_tap_listener=TRUE;
440         }
441 }
442
443 /****************************************************************************/
444
445 void
446 remove_tap_listener_rtp_event(void)
447 {
448         protect_thread_critical_region();
449         remove_tap_listener(&(the_tapinfo_rtp_struct.rtp_event_dummy));
450         unprotect_thread_critical_region();
451
452         have_rtp_event_tap_listener=FALSE;
453 }
454
455 /****************************************************************************/
456 /* ***************************TAP for RTP **********************************/
457 /****************************************************************************/
458
459 /****************************************************************************/
460 /* when there is a [re]reading of RTP packet's */
461 static void voip_rtp_reset(void *ptr _U_)
462 {
463         voip_rtp_tapinfo_t *tapinfo = &the_tapinfo_rtp_struct;
464         GList* list;
465         /* free the data items first */
466         list = g_list_first(tapinfo->list);
467         while (list)
468         {
469                 g_free(list->data);
470                 list = g_list_next(list);
471         }
472         g_list_free(tapinfo->list);
473         tapinfo->list = NULL;
474         tapinfo->nstreams = 0;
475         return;
476 }
477
478 /****************************************************************************/
479 /* whenever a RTP packet is seen by the tap listener */
480 static int 
481 RTP_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, void const *RTPinfo)
482 {
483         voip_rtp_tapinfo_t *tapinfo = &the_tapinfo_rtp_struct;
484         voip_rtp_stream_info_t *tmp_listinfo;
485         voip_rtp_stream_info_t *strinfo = NULL;
486         GList* list;
487         struct _rtp_conversation_info *p_conv_data = NULL;
488
489         const struct _rtp_info *pi = RTPinfo;
490
491         /* do not consider RTP packets without a setup frame */
492         if (pi->info_setup_frame_num == 0){
493                 return 0;
494         }
495
496         /* add this RTP for future listening using the RTP Player*/
497 #if GTK_MAJOR_VERSION >= 2
498 #ifdef HAVE_LIBPORTAUDIO
499         add_rtp_packet(pi, pinfo);
500 #endif
501 #endif
502         
503         /* check wether we already have a RTP stream with this setup frame and ssrc in the list */
504         list = g_list_first(tapinfo->list);
505         while (list)
506         {
507                 tmp_listinfo=list->data;
508                 if ( (tmp_listinfo->setup_frame_number == pi->info_setup_frame_num) 
509                         && (tmp_listinfo->ssrc == pi->info_sync_src) && (tmp_listinfo->end_stream == FALSE)){
510                         /* if the payload type has changed, we mark the stream as finished to create a new one
511                            this is to show multiple payload changes in the Graph for example for DTMF RFC2833 */           
512                         if ( tmp_listinfo->pt != pi->info_payload_type ) {
513                                 tmp_listinfo->end_stream = TRUE;
514                         } else {
515                                 strinfo = (voip_rtp_stream_info_t*)(list->data);
516                                 break;
517                         }
518                 }
519                 list = g_list_next (list);
520         }
521
522         /* if this is a duplicated RTP Event End, just return */
523         if ((rtp_evt_frame_num == pinfo->fd->num) && !strinfo && (rtp_evt_end == TRUE)) {
524                 return 0;
525         }
526
527         /* not in the list? then create a new entry */
528         if (strinfo==NULL){
529                 strinfo = g_malloc(sizeof(voip_rtp_stream_info_t));
530                 COPY_ADDRESS(&(strinfo->src_addr), &(pinfo->src));
531                 strinfo->src_port = pinfo->srcport;
532                 COPY_ADDRESS(&(strinfo->dest_addr), &(pinfo->dst));
533                 strinfo->dest_port = pinfo->destport;
534                 strinfo->ssrc = pi->info_sync_src;
535                 strinfo->end_stream = FALSE;
536                 strinfo->pt = pi->info_payload_type;
537                 strinfo->pt_str = NULL;
538                 /* if it is dynamic payload, let use the conv data to see if it is defined */
539                 if ( (strinfo->pt>95) && (strinfo->pt<128) ) {
540                         /* Use existing packet info if available */
541                         p_conv_data = p_get_proto_data(pinfo->fd, proto_get_id_by_filter_name("rtp"));
542                         if (p_conv_data)
543                                 strinfo->pt_str = g_strdup(g_hash_table_lookup(p_conv_data->rtp_dyn_payload, &strinfo->pt));
544                 }
545                 if (!strinfo->pt_str) strinfo->pt_str = g_strdup(val_to_str(strinfo->pt, rtp_payload_type_short_vals, "%u"));
546                 strinfo->npackets = 0;
547                 strinfo->first_frame_num = pinfo->fd->num;
548                 strinfo->start_rel_sec = pinfo->fd->rel_ts.secs;
549                 strinfo->start_rel_usec = pinfo->fd->rel_ts.nsecs/1000;
550                 strinfo->setup_frame_number = pi->info_setup_frame_num;
551                 strinfo->rtp_event = -1;
552                 tapinfo->list = g_list_append(tapinfo->list, strinfo);
553         }
554
555         if (strinfo!=NULL){
556                 /* Add the info to the existing RTP stream */
557                 strinfo->npackets++;
558                 strinfo->stop_rel_sec = pinfo->fd->rel_ts.secs;
559                 strinfo->stop_rel_usec = pinfo->fd->rel_ts.nsecs/1000;
560
561                 /* process RTP Event */
562                 if (rtp_evt_frame_num == pinfo->fd->num) {
563                         strinfo->rtp_event = rtp_evt;
564                         if (rtp_evt_end == TRUE) {
565                                 strinfo->end_stream = TRUE;
566                         }
567                 }
568         }
569
570         the_tapinfo_struct.redraw = TRUE;
571
572         return 1;
573 }
574
575 /****************************************************************************/
576 /* whenever a redraw in the RTP tap listener */
577 static void RTP_packet_draw(void *prs _U_)
578 {
579         voip_rtp_tapinfo_t *rtp_tapinfo = &the_tapinfo_rtp_struct;
580         GList* rtp_streams_list;
581         voip_rtp_stream_info_t *rtp_listinfo;
582         GList* voip_calls_graph_list;
583         guint item;
584         graph_analysis_item_t *gai;
585         graph_analysis_item_t *new_gai;
586         guint16 conv_num;
587         guint32 duration;
588
589         /* add each rtp stream to the graph */
590         rtp_streams_list = g_list_first(rtp_tapinfo->list);
591         while (rtp_streams_list)
592         {
593                 rtp_listinfo = rtp_streams_list->data;
594
595                 /* using the setup frame number of the RTP stream, we get the call number that it belongs */
596                 voip_calls_graph_list = g_list_first(the_tapinfo_struct.graph_analysis->list);
597                 while (voip_calls_graph_list)
598                 {                       
599                         gai = voip_calls_graph_list->data;
600                         conv_num = gai->conv_num;
601                         /* if we get the setup frame number, then get the time position to graph the RTP arrow */
602                         if (rtp_listinfo->setup_frame_number == gai->frame_num){
603                                 /* look again from the begining because there are cases where the Setup frame is after the RTP */
604                                 voip_calls_graph_list = g_list_first(the_tapinfo_struct.graph_analysis->list);
605                                 item = 0;
606                                 while(voip_calls_graph_list){
607                                         gai = voip_calls_graph_list->data;
608                                         /* if RTP was already in the Graph, just update the comment information */
609                                         if (rtp_listinfo->first_frame_num == gai->frame_num){
610                                                 duration = (rtp_listinfo->stop_rel_sec*1000000 + rtp_listinfo->stop_rel_usec) - (rtp_listinfo->start_rel_sec*1000000 + rtp_listinfo->start_rel_usec);
611                                                 g_free(gai->comment);
612                                                 gai->comment = g_strdup_printf("RTP Num packets:%u  Duration:%u.%03us ssrc:%u", rtp_listinfo->npackets, duration/1000000,(duration%1000000)/1000, rtp_listinfo->ssrc);
613                                                 break;
614                                         /* add the RTP item to the graph if was not there*/
615                                         } else if (rtp_listinfo->first_frame_num<gai->frame_num){
616                                                 new_gai = g_malloc(sizeof(graph_analysis_item_t));
617                                                 new_gai->frame_num = rtp_listinfo->first_frame_num;
618                                                 new_gai->time = (double)rtp_listinfo->start_rel_sec + (double)rtp_listinfo->start_rel_usec/1000000;
619                                                 COPY_ADDRESS(&(new_gai->src_addr),&(rtp_listinfo->src_addr));
620                                                 COPY_ADDRESS(&(new_gai->dst_addr),&(rtp_listinfo->dest_addr));
621                                                 new_gai->port_src = rtp_listinfo->src_port;
622                                                 new_gai->port_dst = rtp_listinfo->dest_port;
623                                                 duration = (rtp_listinfo->stop_rel_sec*1000000 + rtp_listinfo->stop_rel_usec) - (rtp_listinfo->start_rel_sec*1000000 + rtp_listinfo->start_rel_usec);
624                                                 new_gai->frame_label = g_strdup_printf("RTP (%s) %s", rtp_listinfo->pt_str, (rtp_listinfo->rtp_event == -1)?"":val_to_str(rtp_listinfo->rtp_event, rtp_event_type_values, "Unknown RTP Event")); 
625                                                 g_free(rtp_listinfo->pt_str);
626                                                 new_gai->comment = g_strdup_printf("RTP Num packets:%u  Duration:%u.%03us ssrc:%u", rtp_listinfo->npackets, duration/1000000,(duration%1000000)/1000, rtp_listinfo->ssrc);
627                                                 new_gai->conv_num = conv_num;
628                                                 new_gai->display=FALSE;
629                                                 new_gai->line_style = 2;  /* the arrow line will be 2 pixels width */
630                                                 the_tapinfo_struct.graph_analysis->list = g_list_insert(the_tapinfo_struct.graph_analysis->list, new_gai, item);
631                                                 break;
632                                         }
633                                         
634                                         voip_calls_graph_list = g_list_next(voip_calls_graph_list);
635                                         item++;
636                                 }
637                                 break;
638                         }
639                         voip_calls_graph_list = g_list_next(voip_calls_graph_list);
640                 }
641                 rtp_streams_list = g_list_next(rtp_streams_list);
642         }
643 }
644
645 static gboolean have_RTP_tap_listener=FALSE;
646 /****************************************************************************/
647 void
648 rtp_init_tap(void)
649 {
650         GString *error_string;
651
652         if(have_RTP_tap_listener==FALSE)
653         {
654                 /* don't register tap listener, if we have it already */
655                 error_string = register_tap_listener("rtp", &(the_tapinfo_rtp_struct.rtp_dummy), NULL,
656                         voip_rtp_reset, 
657                         RTP_packet, 
658                         RTP_packet_draw
659                         );
660                 if (error_string != NULL) {
661                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
662                                       error_string->str);
663                         g_string_free(error_string, TRUE);
664                         exit(1);
665                 }
666                 have_RTP_tap_listener=TRUE;
667         }
668 }
669
670 /****************************************************************************/
671 void
672 remove_tap_listener_rtp(void)
673 {
674         protect_thread_critical_region();
675         remove_tap_listener(&(the_tapinfo_rtp_struct.rtp_dummy));
676         unprotect_thread_critical_region();
677
678         have_RTP_tap_listener=FALSE;
679 }
680
681 /* XXX just copied from gtk/rpc_stat.c */
682 void protect_thread_critical_region(void);
683 void unprotect_thread_critical_region(void);
684
685 /****************************************************************************/
686 /******************************TAP for T38 **********************************/
687 /****************************************************************************/
688
689 /****************************************************************************/
690 /* whenever a T38 packet is seen by the tap listener */
691 static int 
692 T38_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *T38info)
693 {
694         voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
695
696         voip_calls_info_t *strinfo = NULL;
697         voip_calls_info_t *tmp_listinfo;
698         GList* voip_calls_graph_list;
699         GList* list;
700         gchar *frame_label = NULL;
701         gchar *comment = NULL;
702         graph_analysis_item_t *tmp_gai, *gai = NULL;
703         guint16 line_style = 2;
704         double duration;
705         int conv_num = -1;
706
707         const t38_packet_info *pi = T38info;
708
709         if  (pi->setup_frame_number != 0) {
710                 /* using the setup frame number of the T38 packet, we get the call number that it belongs */
711                 voip_calls_graph_list = g_list_first(tapinfo->graph_analysis->list);
712                 while (voip_calls_graph_list)
713                 {                       
714                         tmp_gai = voip_calls_graph_list->data;
715                         if (pi->setup_frame_number == tmp_gai->frame_num){
716                                 gai = tmp_gai;
717                                 break;
718                         }
719                         voip_calls_graph_list = g_list_next(voip_calls_graph_list);
720                 }
721                 if (gai) conv_num = (int) gai->conv_num;
722         }
723
724         /* 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 
725          * have the associated Voip calls. It probably means the the packet was decoded using the default t38 port, or using "Decode as.."
726          * in this case we create a "voip" call that only have t38 media (no signaling)
727          * OR if we have not found the Setup message in the graph. 
728          */
729         if ( (pi->setup_frame_number == 0) || (gai == NULL) ){
730                 /* check whether we already have a call with these parameters in the list */
731                 list = g_list_first(tapinfo->strinfo_list);
732                 while (list)
733                 {
734                         tmp_listinfo=list->data;
735                         if (tmp_listinfo->protocol == MEDIA_T38){
736                                 strinfo = (voip_calls_info_t*)(list->data);
737                                 break;
738                         }
739                         list = g_list_next (list);
740                 }
741
742                 /* not in the list? then create a new entry */
743                 if (strinfo==NULL){
744                         strinfo = g_malloc(sizeof(voip_calls_info_t));
745                         strinfo->call_active_state = VOIP_ACTIVE;
746                         strinfo->call_state = VOIP_UNKNOWN;
747                         strinfo->from_identity=g_strdup("T38 Media only");
748                         strinfo->to_identity=g_strdup("T38 Media only");
749                         COPY_ADDRESS(&(strinfo->initial_speaker),&(pinfo->src));
750                         strinfo->first_frame_num=pinfo->fd->num;
751                         strinfo->selected=FALSE;
752                         strinfo->start_sec=pinfo->fd->rel_ts.secs;
753                         strinfo->start_usec=pinfo->fd->rel_ts.nsecs/1000;
754                         strinfo->protocol=MEDIA_T38;
755                         strinfo->prot_info=NULL;
756                         strinfo->npackets = 0;
757                         strinfo->call_num = tapinfo->ncalls++;
758                         tapinfo->strinfo_list = g_list_append(tapinfo->strinfo_list, strinfo);
759                 }
760                 ++(strinfo->npackets);
761                 /* increment the packets counter of all calls */
762                 ++(tapinfo->npackets);
763
764                 conv_num = (int) strinfo->call_num;
765         }
766
767         /* at this point we should have found the call num for this t38 packets belong */
768         if (conv_num == -1) {
769                 return 0;
770         }
771
772         /* add the item to the graph list */
773         if (pi->type_msg == 0) { /* 0=t30-indicator */
774                 frame_label = g_strdup(val_to_str(pi->t30ind_value, t30_indicator_vals, "Ukn (0x%02X)") );
775                 comment = g_strdup_printf("t38:t30 Ind:%s",val_to_str(pi->t30ind_value, t30_indicator_vals, "Ukn (0x%02X)") );
776                 line_style = 1;
777         } else if (pi->type_msg == 1) { /* 1=data */
778                 switch(pi->Data_Field_field_type_value){
779                         case 0: /* hdlc-data */
780                                 break;
781                         case 2: /* hdlc-fcs-OK */
782                         case 4: /* hdlc-fcs-OK-sig-end */
783                                         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);
784                                         comment = g_strdup_printf("t38:%s:HDLC:%s",val_to_str(pi->data_value, t30_data_vals, "Ukn (0x%02X)"), val_to_str(pi->t30_Facsimile_Control & 0x7F, t30_facsimile_control_field_vals, "Ukn (0x%02X)"));
785                                 break;
786                         case 3: /* hdlc-fcs-BAD */
787                         case 5: /* hdlc-fcs-BAD-sig-end */
788                                 frame_label = g_strdup(pi->Data_Field_field_type_value == 3 ? "fcs-BAD" : "fcs-BAD-sig-end");
789                                 comment = g_strdup_printf("WARNING: received t38:%s:HDLC:%s", val_to_str(pi->data_value, t30_data_vals, "Ukn (0x%02X)"), pi->Data_Field_field_type_value == 3 ? "fcs-BAD" : "fcs-BAD-sig-end");
790                                 break;
791                         case 7: /* t4-non-ecm-sig-end */
792                                 duration = nstime_to_sec(&pinfo->fd->rel_ts) - pi->time_first_t4_data;
793                                 frame_label = g_strdup_printf("t4-non-ecm-data:%s",val_to_str(pi->data_value, t30_data_vals, "Ukn (0x%02X)") );
794                                 comment = g_strdup_printf("t38:t4-non-ecm-data:%s Duration: %.2fs %s",val_to_str(pi->data_value, t30_data_vals, "Ukn (0x%02X)"), duration, pi->desc_comment );
795                                 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);
796                                 break;
797                 }
798         }
799
800         if (frame_label && !(pi->Data_Field_field_type_value == 7 && pi->type_msg == 1)) {
801                 add_to_graph(tapinfo, pinfo, frame_label, comment, (guint16)conv_num, &(pinfo->src), &(pinfo->dst), line_style);
802         }
803
804         g_free(comment);
805         g_free(frame_label);
806         
807         tapinfo->redraw = TRUE;
808
809         return 1;  /* refresh output */
810 }
811
812 static gboolean have_T38_tap_listener=FALSE;
813 /****************************************************************************/
814 void
815 t38_init_tap(void)
816 {
817         GString *error_string;
818
819         if(have_T38_tap_listener==FALSE)
820         {
821                 /* don't register tap listener, if we have it already */
822                 error_string = register_tap_listener("t38", &(the_tapinfo_struct.t38_dummy), NULL,
823                         voip_calls_dlg_reset, 
824                         T38_packet, 
825                         voip_calls_dlg_draw
826                         );
827                 if (error_string != NULL) {
828                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
829                                       error_string->str);
830                         g_string_free(error_string, TRUE);
831                         exit(1);
832                 }
833                 have_T38_tap_listener=TRUE;
834         }
835 }
836
837 /****************************************************************************/
838 void
839 remove_tap_listener_t38(void)
840 {
841         protect_thread_critical_region();
842         remove_tap_listener(&(the_tapinfo_struct.t38_dummy));
843         unprotect_thread_critical_region();
844
845         have_T38_tap_listener=FALSE;
846 }
847
848
849 /****************************************************************************/
850 static gchar *sdp_summary = NULL;
851 static guint32 sdp_frame_num = 0;
852
853 /****************************************************************************/
854 /* ***************************TAP for SIP **********************************/
855 /****************************************************************************/
856
857 /****************************************************************************/
858 /* whenever a SIP packet is seen by the tap listener */
859 static int 
860 SIPcalls_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *SIPinfo)
861 {
862         voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
863         /* we just take note of the ISUP data here; when we receive the MTP3 part everything will
864            be compared with existing calls */
865
866         voip_calls_info_t *tmp_listinfo;
867         voip_calls_info_t *strinfo = NULL;
868         sip_calls_info_t *tmp_sipinfo = NULL;
869         GList* list;
870         address tmp_src, tmp_dst;
871         gchar *frame_label = NULL;
872         gchar *comment = NULL;
873
874         const sip_info_value_t *pi = SIPinfo;
875
876         /* do not consider packets without call_id */
877         if (pi->tap_call_id ==NULL){
878                 return 0;
879         }
880
881         /* check whether we already have a call with these parameters in the list */
882         list = g_list_first(tapinfo->strinfo_list);
883         while (list)
884         {
885                 tmp_listinfo=list->data;
886                 if (tmp_listinfo->protocol == VOIP_SIP){
887                         tmp_sipinfo = tmp_listinfo->prot_info;
888                         if (strcmp(tmp_sipinfo->call_identifier,pi->tap_call_id)==0){
889                                 strinfo = (voip_calls_info_t*)(list->data);
890                                 break;
891                         }
892                 }
893                 list = g_list_next (list);
894         }
895
896         /* not in the list? then create a new entry if the message is INVITE -i.e. if this session is a call*/
897         if ((strinfo==NULL) &&(pi->request_method!=NULL)){
898                 if (strcmp(pi->request_method,"INVITE")==0){
899                         strinfo = g_malloc(sizeof(voip_calls_info_t));
900                         strinfo->call_active_state = VOIP_ACTIVE;
901                         strinfo->call_state = VOIP_CALL_SETUP;
902                         strinfo->from_identity=g_strdup(pi->tap_from_addr);
903                         strinfo->to_identity=g_strdup(pi->tap_to_addr);
904                         COPY_ADDRESS(&(strinfo->initial_speaker),&(pinfo->src));
905                         strinfo->first_frame_num=pinfo->fd->num;
906                         strinfo->selected=FALSE;
907                         strinfo->start_sec=pinfo->fd->rel_ts.secs;
908                         strinfo->start_usec=pinfo->fd->rel_ts.nsecs/1000;
909                         strinfo->protocol=VOIP_SIP;
910                         strinfo->prot_info=g_malloc(sizeof(sip_calls_info_t));
911                         tmp_sipinfo=strinfo->prot_info;
912                         tmp_sipinfo->call_identifier=strdup(pi->tap_call_id);
913                         tmp_sipinfo->sip_state=SIP_INVITE_SENT;
914                         tmp_sipinfo->invite_cseq=pi->tap_cseq_number;
915                         strinfo->npackets = 0;
916                         strinfo->call_num = tapinfo->ncalls++;
917                         tapinfo->strinfo_list = g_list_append(tapinfo->strinfo_list, strinfo);
918                 }
919         }
920
921         if (strinfo!=NULL){
922
923                 /* let's analyze the call state */
924
925                 COPY_ADDRESS(&(tmp_src), &(pinfo->src));
926                 COPY_ADDRESS(&(tmp_dst), &(pinfo->dst));
927                 
928                 if (pi->request_method == NULL){
929                         frame_label = g_strdup_printf("%u %s", pi->response_code, pi->reason_phrase );
930                         comment = g_strdup_printf("SIP Status");
931
932                         if ((tmp_sipinfo && pi->tap_cseq_number == tmp_sipinfo->invite_cseq)&&(ADDRESSES_EQUAL(&tmp_dst,&(strinfo->initial_speaker)))){
933                                 if ((pi->response_code > 199) && (pi->response_code<300) && (tmp_sipinfo->sip_state == SIP_INVITE_SENT)){
934                                         tmp_sipinfo->sip_state = SIP_200_REC;
935                                 }
936                                 else if ((pi->response_code>299)&&(tmp_sipinfo->sip_state == SIP_INVITE_SENT)){
937                                         strinfo->call_state = VOIP_REJECTED;
938                                         tapinfo->rejected_calls++;
939                                 }
940                         }
941
942                 }
943                 else{
944                         frame_label = g_strdup(pi->request_method);
945
946                         if ((strcmp(pi->request_method,"INVITE")==0)&&(ADDRESSES_EQUAL(&tmp_src,&(strinfo->initial_speaker)))){
947                                 tmp_sipinfo->invite_cseq = pi->tap_cseq_number;
948                                 strinfo->call_state = VOIP_CALL_SETUP;
949                                 comment = g_strdup_printf("SIP From: %s To:%s", strinfo->from_identity, strinfo->to_identity);
950                         }
951                         else if ((strcmp(pi->request_method,"ACK")==0)&&(pi->tap_cseq_number == tmp_sipinfo->invite_cseq)
952                                 &&(ADDRESSES_EQUAL(&tmp_src,&(strinfo->initial_speaker)))&&(tmp_sipinfo->sip_state==SIP_200_REC)
953                                 &&(strinfo->call_state == VOIP_CALL_SETUP)){
954                                 strinfo->call_state = VOIP_IN_CALL;
955                                 comment = g_strdup_printf("SIP Request");
956                         }
957                         else if (strcmp(pi->request_method,"BYE")==0){
958                                 strinfo->call_state = VOIP_COMPLETED;
959                                 tapinfo->completed_calls++;
960                                 comment = g_strdup_printf("SIP Request");
961                         }
962                         else if ((strcmp(pi->request_method,"CANCEL")==0)&&(pi->tap_cseq_number == tmp_sipinfo->invite_cseq)
963                                 &&(ADDRESSES_EQUAL(&tmp_src,&(strinfo->initial_speaker)))&&(strinfo->call_state==VOIP_CALL_SETUP)){
964                                 strinfo->call_state = VOIP_CANCELLED;
965                                 tmp_sipinfo->sip_state = SIP_CANCEL_SENT;
966                                 comment = g_strdup_printf("SIP Request");
967                         } else {
968                                 comment = g_strdup_printf("SIP Request");
969                         }
970                 }
971
972                 strinfo->stop_sec=pinfo->fd->rel_ts.secs;
973                 strinfo->stop_usec=pinfo->fd->rel_ts.nsecs/1000;
974                 strinfo->last_frame_num=pinfo->fd->num;
975                 ++(strinfo->npackets);
976                 /* increment the packets counter of all calls */
977                 ++(tapinfo->npackets);
978
979                 /* add to the graph */
980                 add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);  
981                 g_free(comment);
982                 g_free(frame_label);
983                 g_free((void *)tmp_src.data);
984                 g_free((void *)tmp_dst.data);
985
986                 /* add SDP info if apply */
987                 if ( (sdp_summary != NULL) && (sdp_frame_num == pinfo->fd->num) ){
988                                 append_to_frame_graph(tapinfo, pinfo->fd->num, sdp_summary, NULL);
989                                 g_free(sdp_summary);
990                                 sdp_summary = NULL;
991                 }
992         }
993
994         tapinfo->redraw = TRUE;
995
996         return 1;  /* refresh output */
997 }
998
999
1000 /****************************************************************************/
1001 voip_calls_tapinfo_t* voip_calls_get_info(void)
1002 {
1003         return &the_tapinfo_struct;
1004 }
1005
1006
1007 /****************************************************************************/
1008 /* TAP INTERFACE */
1009 /****************************************************************************/
1010 static gboolean have_SIP_tap_listener=FALSE;
1011 /****************************************************************************/
1012 void
1013 sip_calls_init_tap(void)
1014 {
1015         GString *error_string;
1016
1017         if(have_SIP_tap_listener==FALSE)
1018         {
1019                 /* don't register tap listener, if we have it already */
1020                 error_string = register_tap_listener("sip", &(the_tapinfo_struct.sip_dummy), NULL,
1021                         voip_calls_dlg_reset, 
1022                         SIPcalls_packet, 
1023                         voip_calls_dlg_draw
1024                         );
1025                 if (error_string != NULL) {
1026                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1027                                       error_string->str);
1028                         g_string_free(error_string, TRUE);
1029                         exit(1);
1030                 }
1031                 have_SIP_tap_listener=TRUE;
1032         }
1033 }
1034
1035 /****************************************************************************/
1036 void
1037 remove_tap_listener_sip_calls(void)
1038 {
1039         protect_thread_critical_region();
1040         remove_tap_listener(&(the_tapinfo_struct.sip_dummy));
1041         unprotect_thread_critical_region();
1042
1043         have_SIP_tap_listener=FALSE;
1044 }
1045
1046 /****************************************************************************/
1047 /* ***************************TAP for ISUP **********************************/
1048 /****************************************************************************/
1049
1050 static  guint32         mtp3_opc, mtp3_dpc;
1051 static  guint8          mtp3_ni;
1052 static  guint32         mtp3_frame_num;
1053
1054
1055 /****************************************************************************/
1056 /* whenever a isup_ packet is seen by the tap listener */
1057 static int 
1058 isup_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *isup_info _U_)
1059 {
1060         voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
1061         voip_calls_info_t *tmp_listinfo;
1062         voip_calls_info_t *strinfo = NULL;
1063         isup_calls_info_t *tmp_isupinfo;
1064         gboolean found = FALSE;
1065         gboolean forward = FALSE;
1066         gboolean right_pair;
1067         GList* list;
1068         gchar *frame_label = NULL;
1069         gchar *comment = NULL;
1070         int i;
1071
1072         /*voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct; unused */
1073         const isup_tap_rec_t *pi = isup_info;
1074
1075
1076         /* check if the lower layer is MTP matching the frame number */
1077         if (mtp3_frame_num != pinfo->fd->num) return 0;
1078         
1079         /* check whether we already have a call with these parameters in the list */
1080         list = g_list_first(tapinfo->strinfo_list);
1081         while (list)
1082         {
1083                 right_pair = TRUE;
1084                 tmp_listinfo=list->data;
1085                 if ((tmp_listinfo->protocol == VOIP_ISUP)&&(tmp_listinfo->call_active_state==VOIP_ACTIVE)){
1086                         tmp_isupinfo = tmp_listinfo->prot_info;
1087                         if ((tmp_isupinfo->cic == pinfo->circuit_id)&&(tmp_isupinfo->ni == mtp3_ni)) {
1088                                 if ((tmp_isupinfo->opc == mtp3_opc)&&(tmp_isupinfo->dpc == mtp3_dpc)){
1089                                          forward = TRUE;
1090                                  }
1091                                  else if ((tmp_isupinfo->dpc == mtp3_opc)&&(tmp_isupinfo->opc == mtp3_dpc)){
1092                                          forward = FALSE;
1093                                  }
1094                                  else{
1095                                          right_pair = FALSE;
1096                                  }
1097                                  if (right_pair){
1098                                         /* if there is an IAM for a call that is not in setup state, that means the previous call in the same
1099                                            cic is no longer active */
1100                                         if (tmp_listinfo->call_state == VOIP_CALL_SETUP){
1101                                                 found = TRUE;
1102                                         }
1103                                         else if (pi->message_type != 1){
1104                                                 found = TRUE;
1105                                         }
1106                                         else{
1107                                                 tmp_listinfo->call_active_state=VOIP_INACTIVE;
1108                                         }
1109                                 }
1110                                 if (found){
1111                                         strinfo = (voip_calls_info_t*)(list->data);
1112                                         break;
1113                                 }
1114                         }
1115                 }
1116                 list = g_list_next (list);
1117         }
1118
1119         /* not in the list? then create a new entry if the message is IAM
1120            -i.e. if this session is a call*/
1121
1122
1123         if ((strinfo==NULL) &&(pi->message_type==1)){
1124
1125                 strinfo = g_malloc(sizeof(voip_calls_info_t));
1126                 strinfo->call_active_state = VOIP_ACTIVE;
1127                 strinfo->call_state = VOIP_UNKNOWN;
1128                 COPY_ADDRESS(&(strinfo->initial_speaker),&(pinfo->src));
1129                 strinfo->selected=FALSE;
1130                 strinfo->first_frame_num=pinfo->fd->num;
1131                 strinfo->start_sec=pinfo->fd->rel_ts.secs;
1132                 strinfo->start_usec=pinfo->fd->rel_ts.nsecs/1000;
1133                 strinfo->protocol=VOIP_ISUP;
1134                 if (pi->calling_number!=NULL){
1135                         strinfo->from_identity=g_strdup(pi->calling_number);
1136                 }
1137                 if (pi->called_number!=NULL){
1138                         strinfo->to_identity=g_strdup(pi->called_number);
1139                 }
1140                 strinfo->prot_info=g_malloc(sizeof(isup_calls_info_t));
1141                 tmp_isupinfo=strinfo->prot_info;
1142                 tmp_isupinfo->opc = mtp3_opc;
1143                 tmp_isupinfo->dpc = mtp3_dpc;
1144                 tmp_isupinfo->ni = mtp3_ni;
1145                 tmp_isupinfo->cic = pinfo->circuit_id;
1146                 strinfo->npackets = 0;
1147                 strinfo->call_num = tapinfo->ncalls++;
1148                 tapinfo->strinfo_list = g_list_append(tapinfo->strinfo_list, strinfo);
1149         }
1150
1151         if (strinfo!=NULL){
1152                 strinfo->stop_sec=pinfo->fd->rel_ts.secs;
1153                 strinfo->stop_usec=pinfo->fd->rel_ts.nsecs/1000;
1154                 strinfo->last_frame_num=pinfo->fd->num;
1155                 ++(strinfo->npackets);
1156
1157                 /* Let's analyze the call state */
1158
1159
1160                 for (i=0;(isup_message_type_value[i].strptr!=NULL)&& (isup_message_type_value[i].value!=pi->message_type);i++);
1161
1162                 if (isup_message_type_value[i].value==pi->message_type){
1163                         frame_label = g_strdup(isup_message_type_value_acro[i].strptr);
1164                 }
1165                 else{
1166                         frame_label = g_strdup_printf("Unknown");
1167                 }
1168
1169                 if (strinfo->npackets == 1){ /* this is the first packet, that must be an IAM */
1170                         if ((pi->calling_number!=NULL)&&(pi->called_number !=NULL)){
1171                                 comment = g_strdup_printf("Call from %s to %s",
1172                                  pi->calling_number, pi->called_number);
1173                          }
1174                 }
1175                 else if (strinfo->npackets == 2){ /* in the second packet we show the SPs */
1176                         if (forward){
1177                                 comment = g_strdup_printf("%i-%i -> %i-%i. Cic:%i",
1178                                  mtp3_ni, mtp3_opc,
1179                                  mtp3_ni, mtp3_dpc, pinfo->circuit_id);
1180
1181                         }
1182                         else{
1183                                 comment = g_strdup_printf("%i-%i -> %i-%i. Cic:%i",
1184                                  mtp3_ni, mtp3_dpc,
1185                                  mtp3_ni, mtp3_opc, pinfo->circuit_id);
1186
1187                         }
1188                 }
1189
1190                 switch(pi->message_type){
1191                         case 1: /* IAM */
1192                                 strinfo->call_state=VOIP_CALL_SETUP;
1193                                 break;
1194                         case 7: /* CONNECT */
1195                         case 9: /* ANSWER */
1196                                 strinfo->call_state=VOIP_IN_CALL;
1197                                 break;
1198                         case 12: /* RELEASE */
1199                                 if (strinfo->call_state==VOIP_CALL_SETUP){
1200                                         if (forward){
1201                                                 strinfo->call_state=VOIP_CANCELLED;
1202                                         }
1203                                         else{
1204                                                 strinfo->call_state=VOIP_REJECTED;
1205                                                 tapinfo->rejected_calls++;
1206                                         }
1207                                 }
1208                                 else if (strinfo->call_state == VOIP_IN_CALL){
1209                                         strinfo->call_state = VOIP_COMPLETED;
1210                                         tapinfo->completed_calls++;
1211                                 }
1212                                 for (i=0;(q931_cause_code_vals[i].strptr!=NULL)&& (q931_cause_code_vals[i].value!=pi->cause_value);i++);
1213                                 if (q931_cause_code_vals[i].value==pi->cause_value){
1214                                         comment = g_strdup_printf("Cause %i - %s",pi->cause_value, q931_cause_code_vals[i].strptr);
1215                                 }
1216                                 else{
1217                                         comment = g_strdup_printf("Cause %i",pi->cause_value);
1218                                 }
1219                                 break;
1220                 }
1221
1222                 /* increment the packets counter of all calls */
1223                 ++(tapinfo->npackets);
1224
1225                 /* add to the graph */
1226                 add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);  
1227                 g_free(comment);
1228                 g_free(frame_label);
1229         }
1230
1231         tapinfo->redraw = TRUE;
1232
1233         return 1;  /* refresh output */
1234 }
1235
1236 /****************************************************************************/
1237
1238 static gboolean have_isup_tap_listener=FALSE;
1239
1240 void
1241 isup_calls_init_tap(void)
1242 {
1243         GString *error_string;
1244
1245
1246         if(have_isup_tap_listener==FALSE)
1247         {
1248                 error_string = register_tap_listener("isup", &(the_tapinfo_struct.isup_dummy),
1249                         NULL,
1250                         voip_calls_dlg_reset, 
1251                         isup_calls_packet, 
1252                         voip_calls_dlg_draw
1253                         );
1254         
1255                 if (error_string != NULL) {
1256                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1257                                       error_string->str);
1258                         g_string_free(error_string, TRUE);
1259                         exit(1);
1260                 }
1261                 have_isup_tap_listener=TRUE;
1262         }
1263 }
1264
1265 /****************************************************************************/
1266
1267 void
1268 remove_tap_listener_isup_calls(void)
1269 {
1270         protect_thread_critical_region();
1271         remove_tap_listener(&(the_tapinfo_struct.isup_dummy));
1272         unprotect_thread_critical_region();
1273
1274         have_isup_tap_listener=FALSE;
1275 }
1276
1277
1278 /****************************************************************************/
1279 /* ***************************TAP for MTP3 **********************************/
1280 /****************************************************************************/
1281
1282
1283 /****************************************************************************/
1284 /* whenever a mtp3_ packet is seen by the tap listener */
1285 static int 
1286 mtp3_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *mtp3_info _U_)
1287 {
1288         const mtp3_tap_rec_t *pi = mtp3_info;
1289
1290         /* keep the data in memory to use when the ISUP information arrives */
1291
1292         mtp3_opc = pi->addr_opc.pc;
1293         mtp3_dpc = pi->addr_dpc.pc;
1294         mtp3_ni = pi->addr_opc.ni;
1295         mtp3_frame_num = pinfo->fd->num;
1296
1297         return 0;
1298 }
1299
1300 /****************************************************************************/
1301
1302 static gboolean have_mtp3_tap_listener=FALSE;
1303
1304 void
1305 mtp3_calls_init_tap(void)
1306 {
1307         GString *error_string;
1308
1309
1310         if(have_mtp3_tap_listener==FALSE)
1311         {
1312                 error_string = register_tap_listener("mtp3", &(the_tapinfo_struct.mtp3_dummy),
1313                         NULL,
1314                         voip_calls_dlg_reset, 
1315                         mtp3_calls_packet, 
1316                         voip_calls_dlg_draw
1317                         );
1318
1319                 if (error_string != NULL) {
1320                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1321                                       error_string->str);
1322                         g_string_free(error_string, TRUE);
1323                         exit(1);
1324                 }
1325                 have_mtp3_tap_listener=TRUE;
1326         }
1327 }
1328
1329 /****************************************************************************/
1330
1331 void
1332 remove_tap_listener_mtp3_calls(void)
1333 {
1334         protect_thread_critical_region();
1335         remove_tap_listener(&(the_tapinfo_struct.mtp3_dummy));
1336         unprotect_thread_critical_region();
1337
1338         have_mtp3_tap_listener=FALSE;
1339 }
1340
1341 /****************************************************************************/
1342 /* ***************************TAP for Q931 **********************************/
1343 /****************************************************************************/
1344 void h245_add_to_graph(guint32 new_frame_num);
1345 static const e_guid_t guid_allzero = {0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } };
1346 /* defines specific H323 data */
1347
1348 static gchar *q931_calling_number;
1349 static gchar *q931_called_number;
1350 static guint8 q931_cause_value;
1351 static gint32 q931_crv;
1352 static guint32 q931_frame_num;
1353
1354 static guint32 h225_frame_num = 0;
1355 static guint16 h225_call_num = 0;
1356 static h225_cs_type h225_cstype = H225_OTHER;
1357 static gboolean h225_is_faststart;
1358
1359 static guint32 actrace_frame_num = 0;
1360 static gint32 actrace_trunk = 0;
1361 static gint32 actrace_direction = 0;
1362
1363
1364 /****************************************************************************/
1365 /* whenever a q931_ packet is seen by the tap listener */
1366 static int 
1367 q931_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *q931_info _U_)
1368 {
1369         GList *list,*list2;
1370         voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct; 
1371         h323_calls_info_t *tmp_h323info,*tmp2_h323info;
1372         actrace_isdn_calls_info_t *tmp_actrace_isdn_info;
1373         voip_calls_info_t *tmp_listinfo;
1374         voip_calls_info_t *strinfo = NULL;
1375         h245_address_t *h245_add = NULL;
1376         gchar *comment;
1377
1378         const q931_packet_info *pi = q931_info;
1379
1380         /* free previously allocated q931_calling/ed_number */
1381         g_free(q931_calling_number);
1382         g_free(q931_called_number);
1383         
1384         if (pi->calling_number!=NULL)
1385                 q931_calling_number = g_strdup(pi->calling_number);
1386         else
1387                 q931_calling_number = g_strdup("");
1388
1389         if (pi->called_number!=NULL)
1390                 q931_called_number = g_strdup(pi->called_number);
1391         else
1392                 q931_called_number = g_strdup("");
1393         q931_cause_value = pi->cause_value;
1394         q931_frame_num = pinfo->fd->num;
1395         q931_crv = pi->crv;
1396
1397
1398         /* add staff to H323 calls */
1399         if (h225_frame_num == q931_frame_num) {
1400                 tmp_h323info = NULL;
1401                 list = g_list_first(tapinfo->strinfo_list);
1402                 while (list)
1403                 {
1404                         tmp_listinfo=list->data;
1405                         if ( (tmp_listinfo->protocol == VOIP_H323) && (tmp_listinfo->call_num == h225_call_num) ){
1406                                 tmp_h323info = tmp_listinfo->prot_info;
1407                                 strinfo = (voip_calls_info_t*)(list->data);
1408
1409                                 /* Add the CRV to the h323 call */
1410                                 if (tmp_h323info->q931_crv == -1) {
1411                                         tmp_h323info->q931_crv = q931_crv;
1412                                 } else if (tmp_h323info->q931_crv != q931_crv) {
1413                                         tmp_h323info->q931_crv2 = q931_crv;
1414                                 }
1415                                 break;
1416                         }
1417                         list = g_list_next (list);
1418                 }
1419
1420                 if (strinfo != NULL) {
1421                         comment = NULL;
1422                         if (h225_cstype == H225_SETUP) {
1423                                 /* set te calling and called number from the Q931 packet */
1424                                 if (q931_calling_number != NULL){
1425                                         g_free(strinfo->from_identity);
1426                                         strinfo->from_identity=g_strdup(q931_calling_number);
1427                                 }
1428                                 if (q931_called_number != NULL){
1429                                         g_free(strinfo->to_identity);
1430                                         strinfo->to_identity=g_strdup(q931_called_number);
1431                                 }
1432
1433                                 /* check if there is an LRQ/LCF that match this Setup */
1434                                 /* TODO: we are just checking the DialedNumer in LRQ/LCF agains the Setup 
1435                                         we should also check if the h225 signaling IP and port match the destination 
1436                                         Setup ip and port */
1437                                 list = g_list_first(tapinfo->strinfo_list);
1438                                 while (list)
1439                                 {
1440                                         tmp_listinfo=list->data;
1441                                         if (tmp_listinfo->protocol == VOIP_H323){
1442                                                 tmp2_h323info = tmp_listinfo->prot_info;
1443                                                 
1444                                                 /* check if the called number match a LRQ/LCF */
1445                                                 if ( (strcmp(strinfo->to_identity, tmp_listinfo->to_identity)==0)  
1446                                                          && (memcmp(&tmp2_h323info->guid, &guid_allzero, GUID_LEN) == 0) ){ 
1447                                                         /* change the call graph to the LRQ/LCF to belong to this call */
1448                                                         strinfo->npackets += change_call_num_graph(tapinfo, tmp_listinfo->call_num, strinfo->call_num);
1449                                                         
1450                                                         /* remove this LRQ/LCF call entry because we have found the Setup that match them */
1451                                                         g_free(tmp_listinfo->from_identity);
1452                                                         g_free(tmp_listinfo->to_identity);
1453                                                         g_free(tmp2_h323info->guid);
1454                                                         
1455                                                         list2 = g_list_first(tmp2_h323info->h245_list);
1456                                                         while (list2)
1457                                                         {
1458                                                                 h245_add=list2->data;
1459                                                                 g_free((void *)h245_add->h245_address.data);
1460                                                                 g_free(list2->data);
1461                                                                 list2 = g_list_next(list2);
1462                                                         }
1463                                                         g_list_free(tmp_h323info->h245_list);
1464                                                         tmp_h323info->h245_list = NULL;
1465                                                         g_free(tmp_listinfo->prot_info);
1466                                                         tapinfo->strinfo_list = g_list_remove(tapinfo->strinfo_list, tmp_listinfo);
1467                                                         break;
1468                                                 }
1469                                         }
1470                                 list = g_list_next (list);
1471                                 }
1472
1473                                 comment = g_strdup_printf("H225 From: %s To:%s  TunnH245:%s FS:%s", strinfo->from_identity, strinfo->to_identity, (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"), 
1474                                                           (h225_is_faststart==TRUE?"on":"off"));
1475                         } else if (h225_cstype == H225_RELEASE_COMPLET) {
1476                                 /* get the Q931 Release cause code */
1477                                 if (q931_cause_value != 0xFF){          
1478                                         comment = g_strdup_printf("H225 Q931 Rel Cause (%i):%s", q931_cause_value, val_to_str(q931_cause_value, q931_cause_code_vals, "<unknown>"));
1479                                 } else { /* Cause not set */
1480                                         comment = g_strdup("H225 No Q931 Rel Cause");
1481                                 }
1482                         }
1483                         /* change the graph comment for this new one */
1484                         if (comment != NULL) {
1485                                 change_frame_graph(tapinfo, h225_frame_num, NULL, comment);
1486                                 g_free(comment);
1487                         }
1488                 }
1489                 /* we reset the h225_frame_num to 0 because there could be empty h225 in the same frame
1490                    as non empty h225 (e.g connect), so we don't have to be here twice */
1491                 h225_frame_num = 0;
1492
1493         /* add staff to H245 */
1494         } else if (h245_labels.frame_num == q931_frame_num) {
1495         /* there are empty H225 frames that don't have guid (guaid=0) but they have h245 info, 
1496            so the only way to match those frames is with the Q931 CRV number */ 
1497                 list = g_list_first(tapinfo->strinfo_list);
1498                 while (list)
1499                 {
1500                         tmp_listinfo=list->data;
1501                         if (tmp_listinfo->protocol == VOIP_H323){
1502                                 tmp_h323info = tmp_listinfo->prot_info;
1503                                 if ( ((tmp_h323info->q931_crv == q931_crv) || (tmp_h323info->q931_crv2 == q931_crv)) && (q931_crv!=-1)){
1504
1505                                         comment = g_strdup("");
1506
1507                                         /* if the frame number exists in graph, append to it*/
1508                                         if (!append_to_frame_graph(tapinfo, q931_frame_num, "", comment)) {
1509                                                 /* if not exist, add to the graph */
1510                                                 add_to_graph(tapinfo, pinfo, "", comment, tmp_listinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
1511                                                 ++(tmp_listinfo->npackets);
1512                                                 /* increment the packets counter of all calls */
1513                                                 ++(tapinfo->npackets);
1514                                         }
1515                                         
1516                                         /* Add the H245 info if exists to the Graph */
1517                                         h245_add_to_graph(pinfo->fd->num);
1518                                         g_free(comment);
1519                                         break;
1520                                 }
1521                         }
1522                         list = g_list_next (list);
1523                 }
1524
1525         /* add staff to ACTRACE */
1526         } else if (actrace_frame_num == q931_frame_num) {
1527                 address pstn_add;
1528                 gchar *comment = NULL;
1529
1530                 strinfo = NULL;
1531                 list = g_list_first(tapinfo->strinfo_list);
1532                 while (list)
1533                 {
1534                         tmp_listinfo=list->data;
1535                         if ( tmp_listinfo->protocol == VOIP_AC_ISDN ){
1536                                 tmp_actrace_isdn_info = tmp_listinfo->prot_info;
1537                                 /* TODO: Also check the IP of the Blade, and if the call is complete (no active) */
1538                                 if ( (tmp_actrace_isdn_info->crv == q931_crv) && (tmp_actrace_isdn_info->trunk == actrace_trunk) ) {
1539                                         strinfo = (voip_calls_info_t*)(list->data);
1540                                         break;
1541                                 }
1542                         }
1543                         list = g_list_next (list);
1544                 }
1545
1546                 SET_ADDRESS(&pstn_add, AT_STRINGZ, 5, g_strdup("PSTN"));
1547
1548                 /* if it is a new call, add it to the list */
1549                 if (!strinfo) {
1550                         strinfo = g_malloc(sizeof(voip_calls_info_t));
1551                         strinfo->call_active_state = VOIP_ACTIVE;
1552                         strinfo->call_state = VOIP_CALL_SETUP;
1553                         strinfo->from_identity=g_strdup(q931_calling_number);
1554                         strinfo->to_identity=g_strdup(q931_called_number);
1555                         COPY_ADDRESS(&(strinfo->initial_speaker),actrace_direction?&pstn_add:&(pinfo->src));
1556                         strinfo->first_frame_num=pinfo->fd->num;
1557                         strinfo->selected=FALSE;
1558                         strinfo->start_sec=pinfo->fd->rel_ts.secs;
1559                         strinfo->start_usec=pinfo->fd->rel_ts.nsecs/1000;
1560                         strinfo->protocol=VOIP_AC_ISDN;
1561                         strinfo->prot_info=g_malloc(sizeof(actrace_isdn_calls_info_t));
1562                         tmp_actrace_isdn_info=strinfo->prot_info;
1563                         tmp_actrace_isdn_info->crv=q931_crv;
1564                         tmp_actrace_isdn_info->trunk=actrace_trunk;
1565                         strinfo->npackets = 0;
1566                         strinfo->call_num = tapinfo->ncalls++;
1567                         tapinfo->strinfo_list = g_list_append(tapinfo->strinfo_list, strinfo);
1568                 }
1569
1570                 strinfo->stop_sec=pinfo->fd->rel_ts.secs;
1571                 strinfo->stop_usec=pinfo->fd->rel_ts.nsecs/1000;
1572                 strinfo->last_frame_num=pinfo->fd->num;
1573                 ++(strinfo->npackets);
1574                 /* increment the packets counter of all calls */
1575                 ++(tapinfo->npackets);
1576
1577                 switch(pi->message_type){
1578                 case Q931_SETUP:
1579                         comment = g_strdup_printf("AC_ISDN trunk:%u Calling: %s  Called:%s", actrace_trunk, q931_calling_number, q931_called_number);
1580                         strinfo->call_state=VOIP_CALL_SETUP;
1581                         break;
1582                 case Q931_CONNECT:
1583                         strinfo->call_state=VOIP_IN_CALL;
1584                         break;
1585                 case Q931_RELEASE_COMPLETE:
1586                 case Q931_RELEASE:
1587                 case Q931_DISCONNECT:
1588                         if (strinfo->call_state==VOIP_CALL_SETUP){
1589                                 if (ADDRESSES_EQUAL(&(strinfo->initial_speaker), actrace_direction?&pstn_add:&(pinfo->src) )){  /* forward direction */
1590                                         strinfo->call_state=VOIP_CANCELLED;
1591                                 }
1592                                 else{                                                                                           /* reverse */
1593                                         strinfo->call_state=VOIP_REJECTED;
1594                                         tapinfo->rejected_calls++;
1595                                 }
1596                         } else if ( (strinfo->call_state!=VOIP_CANCELLED) && (strinfo->call_state!=VOIP_REJECTED) ){
1597                                         strinfo->call_state=VOIP_COMPLETED;
1598                                         tapinfo->completed_calls++;
1599                         }
1600                         if (q931_cause_value != 0xFF){          
1601                                 comment = g_strdup_printf("AC_ISDN trunk:%u Q931 Rel Cause (%i):%s", actrace_trunk, q931_cause_value, val_to_str(q931_cause_value, q931_cause_code_vals, "<unknown>"));
1602                         } else { /* Cause not set */
1603                                 comment = g_strdup("AC_ISDN No Q931 Rel Cause");
1604                         }
1605                         break;
1606                 }
1607
1608                 if (!comment)
1609                         comment = g_strdup_printf("AC_ISDN  trunk:%u", actrace_trunk );
1610
1611                 add_to_graph(tapinfo, pinfo, val_to_str(pi->message_type, q931_message_type_vals, "<unknown>") , comment, strinfo->call_num, 
1612                                 actrace_direction?&pstn_add:&(pinfo->src),
1613                                 actrace_direction?&(pinfo->src):&pstn_add,
1614                                 1 );
1615
1616                 g_free(comment);
1617                 g_free((char *)pstn_add.data);
1618         }
1619
1620         tapinfo->redraw = TRUE;
1621
1622         return 1;  /* refresh output */
1623 }
1624
1625 /****************************************************************************/
1626 static gboolean have_q931_tap_listener=FALSE;
1627
1628 void
1629 q931_calls_init_tap(void)
1630 {
1631         GString *error_string;
1632
1633
1634         if(have_q931_tap_listener==FALSE)
1635         {
1636                 error_string = register_tap_listener("q931", &(the_tapinfo_struct.q931_dummy),
1637                         NULL,
1638                         voip_calls_dlg_reset,
1639                         q931_calls_packet,
1640                         voip_calls_dlg_draw
1641                         );
1642                         
1643                 if (error_string != NULL) {
1644                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1645                                       error_string->str);
1646                         g_string_free(error_string, TRUE);
1647                         exit(1);
1648                 }
1649                 have_q931_tap_listener=TRUE;
1650         }
1651 }
1652
1653 /****************************************************************************/
1654
1655 void
1656 remove_tap_listener_q931_calls(void)
1657 {
1658         protect_thread_critical_region();
1659         remove_tap_listener(&(the_tapinfo_struct.q931_dummy));
1660         unprotect_thread_critical_region();
1661
1662         have_q931_tap_listener=FALSE;
1663 }
1664
1665 /****************************************************************************/
1666 /****************************TAP for H323 ***********************************/
1667 /****************************************************************************/
1668
1669 static void add_h245_Address(h323_calls_info_t *h323info,  h245_address_t *h245_address)
1670 {
1671         h323info->h245_list = g_list_append(h323info->h245_list, h245_address);                         
1672 }
1673
1674 /****************************************************************************/
1675 /* whenever a H225 packet is seen by the tap listener */
1676 static int 
1677 H225calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *H225info)
1678 {
1679         voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
1680         voip_calls_info_t *tmp_listinfo;
1681         voip_calls_info_t *strinfo = NULL;
1682         h323_calls_info_t *tmp_h323info = NULL;
1683         gchar *frame_label;
1684         gchar *comment;
1685         GList *list;
1686         address tmp_src, tmp_dst;
1687         h245_address_t *h245_add = NULL;
1688         
1689         const h225_packet_info *pi = H225info;
1690         
1691         /* if not guid and RAS and not LRQ, LCF or LRJ return because did not belong to a call */
1692         /* OR, if not guid and is H225 return because doesn't belong to a call */
1693         if ((memcmp(&pi->guid, &guid_allzero, GUID_LEN) == 0))
1694                 if ( ((pi->msg_type == H225_RAS) && ((pi->msg_tag < 18) || (pi->msg_tag > 20))) || (pi->msg_type != H225_RAS) )
1695                         return 0;
1696         
1697         /* if it is RAS LCF or LRJ*/
1698         if ( (pi->msg_type == H225_RAS) && ((pi->msg_tag == 19) || (pi->msg_tag == 20))) { 
1699                 /* if the LCF/LRJ doesn't match to a LRQ, just return */
1700                 if (!pi->request_available) return 0;
1701                 
1702                 /* check whether we already have a call with this request SeqNum */
1703                 list = g_list_first(tapinfo->strinfo_list);
1704                 while (list)
1705                 {
1706                         tmp_listinfo=list->data;
1707                         g_assert(tmp_listinfo != NULL);
1708                         if (tmp_listinfo->protocol == VOIP_H323){
1709                                 tmp_h323info = tmp_listinfo->prot_info;
1710                                 if (tmp_h323info->requestSeqNum == pi->requestSeqNum) {
1711                                         strinfo = (voip_calls_info_t*)(list->data);
1712                                         break;
1713                                 }
1714                         }
1715                         list = g_list_next (list);
1716                 }
1717         } else {
1718                 /* check whether we already have a call with this guid in the list */
1719                 list = g_list_first(tapinfo->strinfo_list);
1720                 while (list)
1721                 {
1722                         tmp_listinfo=list->data;
1723                         if (tmp_listinfo->protocol == VOIP_H323){
1724                                 tmp_h323info = tmp_listinfo->prot_info;
1725                                 g_assert(tmp_h323info != NULL);
1726                                 if ( (memcmp(tmp_h323info->guid, &guid_allzero, GUID_LEN) != 0) && (memcmp(tmp_h323info->guid, &pi->guid,GUID_LEN)==0) ){ 
1727                                         strinfo = (voip_calls_info_t*)(list->data);
1728                                         break;
1729                                 }
1730                         }
1731                         list = g_list_next (list);
1732                 }
1733         }
1734         
1735         h225_cstype = pi->cs_type;
1736         h225_is_faststart = pi->is_faststart;
1737
1738         /* not in the list? then create a new entry */
1739         if ((strinfo==NULL)){
1740                 strinfo = g_malloc(sizeof(voip_calls_info_t));
1741                 strinfo->call_active_state = VOIP_ACTIVE;
1742                 strinfo->call_state = VOIP_UNKNOWN;
1743                 strinfo->from_identity=g_strdup("");
1744                 strinfo->to_identity=g_strdup("");
1745                 COPY_ADDRESS(&(strinfo->initial_speaker),&(pinfo->src));
1746                 strinfo->selected=FALSE;
1747                 strinfo->first_frame_num=pinfo->fd->num;
1748                 strinfo->start_sec=pinfo->fd->rel_ts.secs;
1749                 strinfo->start_usec=pinfo->fd->rel_ts.nsecs/1000;
1750                 strinfo->protocol=VOIP_H323;
1751                 strinfo->prot_info=g_malloc(sizeof(h323_calls_info_t));
1752                 tmp_h323info = strinfo->prot_info;
1753                 g_assert(tmp_h323info != NULL);
1754                 tmp_h323info->guid = g_memdup(&pi->guid, sizeof pi->guid);
1755                 tmp_h323info->h225SetupAddr.type = AT_NONE;
1756                 tmp_h323info->h225SetupAddr.len = 0;
1757                 tmp_h323info->h245_list = NULL;
1758                 tmp_h323info->is_faststart_Setup = FALSE;
1759                 tmp_h323info->is_faststart_Proc = FALSE;
1760                 tmp_h323info->is_h245Tunneling = FALSE;
1761                 tmp_h323info->is_h245 = FALSE;
1762                 tmp_h323info->q931_crv = -1;
1763                 tmp_h323info->q931_crv2 = -1;
1764                 tmp_h323info->requestSeqNum = 0;
1765                 strinfo->call_num = tapinfo->ncalls++;
1766                 strinfo->npackets = 0;
1767                 
1768                 tapinfo->strinfo_list = g_list_append(tapinfo->strinfo_list, strinfo);                          
1769         }
1770
1771         if (strinfo!=NULL){
1772
1773                 h225_frame_num = pinfo->fd->num;
1774                 h225_call_num = strinfo->call_num;
1775
1776                 /* let's analyze the call state */
1777
1778                 COPY_ADDRESS(&(tmp_src),&(pinfo->src));
1779                 COPY_ADDRESS(&(tmp_dst),&(pinfo->dst));
1780
1781                 strinfo->stop_sec=pinfo->fd->rel_ts.secs;
1782                 strinfo->stop_usec=pinfo->fd->rel_ts.nsecs/1000;
1783                 strinfo->last_frame_num=pinfo->fd->num;
1784                 ++(strinfo->npackets);
1785                 /* increment the packets counter of all calls */
1786                 ++(tapinfo->npackets);
1787
1788
1789                 /* XXX: it is supposed to be initialized isn't it? */
1790                 g_assert(tmp_h323info != NULL);
1791
1792                 /* change the status */
1793                 if (pi->msg_type == H225_CS){
1794
1795                         /* this is still IPv4 only, because the dissector is */
1796                         if (pi->is_h245 == TRUE){
1797                                 h245_add = g_malloc(sizeof (h245_address_t));
1798                                 h245_add->h245_address.type=AT_IPv4;
1799                                 h245_add->h245_address.len=4;
1800                                 h245_add->h245_address.data = g_malloc(sizeof(pi->h245_address));
1801                                 g_memmove((void *)(h245_add->h245_address.data), &(pi->h245_address), 4);
1802                                 h245_add->h245_port = pi->h245_port;
1803                                 add_h245_Address(tmp_h323info, h245_add);
1804                         }
1805
1806                         if (pi->cs_type != H225_RELEASE_COMPLET) tmp_h323info->is_h245Tunneling = pi->is_h245Tunneling;
1807
1808                         frame_label = g_strdup(pi->frame_label);
1809
1810                         switch(pi->cs_type){
1811                         case H225_SETUP:
1812                                 tmp_h323info->is_faststart_Setup = pi->is_faststart;
1813
1814                                 /* Set the Setup address if it was not set */
1815                                 if (tmp_h323info->h225SetupAddr.type == AT_NONE) 
1816                                   COPY_ADDRESS(&(tmp_h323info->h225SetupAddr), &(pinfo->src));
1817                                         strinfo->call_state=VOIP_CALL_SETUP;
1818                                 comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"), 
1819                                                                                   (pi->is_faststart==TRUE?"on":"off"));
1820                                 break;
1821                         case H225_CONNECT:
1822                                 strinfo->call_state=VOIP_IN_CALL;
1823                                 if (pi->is_faststart == TRUE) tmp_h323info->is_faststart_Proc = TRUE;
1824                                         comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"), 
1825                                                                                           (pi->is_faststart==TRUE?"on":"off"));
1826                                 break;
1827                         case H225_RELEASE_COMPLET:
1828                             COPY_ADDRESS(&tmp_src,&(pinfo->src));
1829                                 if (strinfo->call_state==VOIP_CALL_SETUP){
1830                                         if (ADDRESSES_EQUAL(&(tmp_h323info->h225SetupAddr),&tmp_src)){  /* forward direction */
1831                                                 strinfo->call_state=VOIP_CANCELLED;
1832                                         }
1833                                         else{                                                                                           /* reverse */
1834                                                 strinfo->call_state=VOIP_REJECTED;
1835                                                 tapinfo->rejected_calls++;
1836                                         }
1837                                 } else {
1838                                                 strinfo->call_state=VOIP_COMPLETED;
1839                                                 tapinfo->completed_calls++;
1840                                 }
1841                                 comment = g_strdup("H225 No Q931 Rel Cause");
1842                                 break;
1843                         case H225_PROGRESS:
1844                         case H225_ALERTING:
1845                         case H225_CALL_PROCEDING:
1846                                 if (pi->is_faststart == TRUE) tmp_h323info->is_faststart_Proc = TRUE;
1847                                 comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"), 
1848                                                                                   (pi->is_faststart==TRUE?"on":"off"));
1849                                 break;
1850                         default:
1851                                 comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"), 
1852                                                                                   (pi->is_faststart==TRUE?"on":"off"));
1853                                 
1854                         } 
1855                 } 
1856                 else if (pi->msg_type == H225_RAS){
1857                 switch(pi->msg_tag){
1858                         case 18:  /* LRQ */
1859                                 if (!pi->is_duplicate){
1860                                         g_free(strinfo->to_identity);
1861                                         strinfo->to_identity=g_strdup(pi->dialedDigits);
1862                                         tmp_h323info->requestSeqNum = pi->requestSeqNum;
1863                                 }
1864                         case 19: /* LCF */
1865                                 if (strlen(pi->dialedDigits)) 
1866                                         comment = g_strdup_printf("H225 RAS dialedDigits: %s", pi->dialedDigits);
1867                                 else
1868                                         comment = g_strdup("H225 RAS");
1869                                 break;
1870                         default:
1871                                 comment = g_strdup("H225 RAS");
1872                 }
1873                 frame_label = g_strdup_printf("%s", val_to_str(pi->msg_tag, RasMessage_vals, "<unknown>"));
1874         } else {
1875                 frame_label = g_strdup("H225: Unknown");
1876                 comment = g_strdup("");
1877         }
1878
1879         /* add to graph analysis */
1880
1881         /* if the frame number exists in graph, append to it*/
1882         if (!append_to_frame_graph(tapinfo, pinfo->fd->num, pi->frame_label, comment)) {
1883                 /* if not exist, add to the graph */
1884                 add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
1885                 g_free((void *)tmp_src.data);
1886                 g_free((void *)tmp_dst.data);
1887         }
1888
1889         /* Add the H245 info if exists to the Graph */
1890         h245_add_to_graph(pinfo->fd->num);
1891
1892         g_free(frame_label);
1893         g_free(comment);
1894         
1895         } 
1896         
1897         tapinfo->redraw = TRUE;
1898
1899         return 1;  /* refresh output */
1900 }
1901
1902
1903 /****************************************************************************/
1904 /* TAP INTERFACE */
1905 /****************************************************************************/
1906 static gboolean have_H225_tap_listener=FALSE;
1907 /****************************************************************************/
1908 void
1909 h225_calls_init_tap(void)
1910 {
1911         GString *error_string;
1912
1913         if(have_H225_tap_listener==FALSE)
1914         {
1915                 /* don't register tap listener, if we have it already */
1916                 error_string = register_tap_listener("h225", &(the_tapinfo_struct.h225_dummy), NULL,
1917                         voip_calls_dlg_reset, 
1918                         H225calls_packet, 
1919                         voip_calls_dlg_draw
1920                         );
1921                         
1922                 if (error_string != NULL) {
1923                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1924                                       error_string->str);
1925                         g_string_free(error_string, TRUE);
1926                         exit(1);
1927                 }
1928                 have_H225_tap_listener=TRUE;
1929         }
1930 }
1931
1932 /****************************************************************************/
1933 void
1934 remove_tap_listener_h225_calls(void)
1935 {
1936         protect_thread_critical_region();
1937         remove_tap_listener(&(the_tapinfo_struct.h225_dummy));
1938         unprotect_thread_critical_region();
1939
1940         have_H225_tap_listener=FALSE;
1941 }
1942
1943 /* Add the h245 label info to the graph */ 
1944 void h245_add_to_graph(guint32 new_frame_num)
1945 {
1946         gint8 n;
1947         
1948         if (new_frame_num != h245_labels.frame_num) return;
1949
1950         for (n=0; n<h245_labels.labels_count; n++) {
1951                 append_to_frame_graph(&the_tapinfo_struct, new_frame_num, h245_labels.labels[n].frame_label, h245_labels.labels[n].comment);
1952                 g_free(h245_labels.labels[n].frame_label);
1953                 h245_labels.labels[n].frame_label = NULL;
1954                 g_free(h245_labels.labels[n].comment);
1955                 h245_labels.labels[n].comment = NULL;
1956         }
1957         h245_labels.frame_num = 0;
1958         h245_labels.labels_count = 0;
1959 }
1960
1961 /* free the h245_labels if the frame number is different */ 
1962 static void h245_free_labels(guint32 new_frame_num)
1963 {
1964         gint8 n;
1965         
1966         if (new_frame_num == h245_labels.frame_num) return;
1967
1968         for (n=0; n<h245_labels.labels_count; n++) {
1969                 g_free(h245_labels.labels[n].frame_label);
1970                 h245_labels.labels[n].frame_label = NULL;
1971                 g_free(h245_labels.labels[n].comment);
1972                 h245_labels.labels[n].comment = NULL;
1973         }
1974         h245_labels.frame_num = 0;
1975         h245_labels.labels_count = 0;
1976 }
1977
1978 /* add the frame_label and comment to h245_labels and free the actual one if it is different frame num */ 
1979 static void h245_add_label(guint32 new_frame_num, gchar *frame_label, gchar *comment)
1980 {
1981         h245_free_labels(new_frame_num);
1982
1983         h245_labels.frame_num = new_frame_num;
1984         h245_labels.labels[h245_labels.labels_count].frame_label = g_strdup(frame_label);
1985         h245_labels.labels[h245_labels.labels_count].comment = g_strdup(comment);
1986
1987         if (h245_labels.labels_count < (H245_MAX-1))
1988                 h245_labels.labels_count++;
1989
1990 }
1991
1992 /****************************************************************************/
1993 /* whenever a H245dg packet is seen by the tap listener (when H245 tunneling is ON) */
1994 static int 
1995 H245dgcalls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *H245info)
1996 {
1997         voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
1998         voip_calls_info_t *tmp_listinfo;
1999         voip_calls_info_t *strinfo = NULL;
2000         h323_calls_info_t *tmp_h323info;
2001         gchar *frame_label;
2002         gchar *comment;
2003         GList* list;
2004         GList* list2;
2005         address tmp_src, tmp_dst;
2006         h245_address_t *h245_add = NULL;
2007
2008         const h245_packet_info *pi = H245info;
2009
2010         /* check if Tunneling is OFF and we have a call with this H245 add */
2011         list = g_list_first(tapinfo->strinfo_list);
2012         while (list)
2013         {
2014                 tmp_listinfo=list->data;
2015                 if (tmp_listinfo->protocol == VOIP_H323){
2016                         tmp_h323info = tmp_listinfo->prot_info;
2017
2018                         COPY_ADDRESS(&(tmp_src), &(pinfo->src));
2019                         COPY_ADDRESS(&(tmp_dst), &(pinfo->dst));
2020                         list2 = g_list_first(tmp_h323info->h245_list);
2021                         while (list2)
2022                         {
2023                                 h245_add=list2->data;
2024                                 if ( (ADDRESSES_EQUAL(&(h245_add->h245_address),&tmp_src) && (h245_add->h245_port == pinfo->srcport))
2025                                         || (ADDRESSES_EQUAL(&(h245_add->h245_address),&tmp_dst) && (h245_add->h245_port == pinfo->destport)) ){
2026                                         strinfo = (voip_calls_info_t*)(list->data);
2027
2028                                         ++(strinfo->npackets);
2029                                         /* increment the packets counter of all calls */
2030                                         ++(tapinfo->npackets);
2031
2032                                         break;
2033                                 }                       
2034                         list2 = g_list_next(list2);
2035                         }
2036                         if (strinfo!=NULL) break;
2037                         g_free((void *)tmp_src.data);
2038                         g_free((void *)tmp_dst.data);
2039                 }
2040                 list = g_list_next(list);
2041         }
2042
2043         /* Tunnel is OFF, and we matched the h245 add so we add it to graph */
2044         if (strinfo!=NULL){
2045                 ++(strinfo->npackets);
2046                 /* increment the packets counter of all calls */
2047                 ++(tapinfo->npackets);
2048                 frame_label = g_strdup(pi->frame_label);
2049                 comment = g_strdup(pi->comment);
2050                 /* if the frame number exists in graph, append to it*/
2051                 if (!append_to_frame_graph(tapinfo, pinfo->fd->num, frame_label, comment)) {
2052                         /* if not exist, add to the graph */
2053                         add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
2054                 }
2055                 g_free(frame_label);
2056                 g_free(comment);
2057         } else { 
2058         /* Tunnel is ON, so we save the label info to use it into h225 or q931 tap. OR may be 
2059                  tunnel OFF but we did not matched the h245 add, in this case nobady will set this label 
2060                  since the frame_num will not match */ 
2061         
2062                 h245_add_label(pinfo->fd->num, (gchar *) pi->frame_label, (gchar *) pi->comment);
2063         }
2064
2065         tapinfo->redraw = TRUE;
2066
2067         return 1;  /* refresh output */
2068 }
2069
2070
2071 /****************************************************************************/
2072 /* TAP INTERFACE */
2073 /****************************************************************************/
2074 static gboolean have_H245dg_tap_listener=FALSE;
2075 /****************************************************************************/
2076 void
2077 h245dg_calls_init_tap(void)
2078 {
2079         GString *error_string;
2080
2081         if(have_H245dg_tap_listener==FALSE)
2082         {
2083                 /* don't register tap listener, if we have it already */
2084                 error_string = register_tap_listener("h245dg", &(the_tapinfo_struct.h245dg_dummy), NULL,
2085                         voip_calls_dlg_reset,
2086                         H245dgcalls_packet, 
2087                         voip_calls_dlg_draw
2088                         );
2089                 
2090                 if (error_string != NULL) {
2091                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2092                                       error_string->str);
2093                         g_string_free(error_string, TRUE);
2094                         exit(1);
2095                 }
2096                 have_H245dg_tap_listener=TRUE;
2097         }
2098 }
2099
2100 /****************************************************************************/
2101 void
2102 remove_tap_listener_h245dg_calls(void)
2103 {
2104         protect_thread_critical_region();
2105         remove_tap_listener(&(the_tapinfo_struct.h245dg_dummy));
2106         unprotect_thread_critical_region();
2107
2108         have_H245dg_tap_listener=FALSE;
2109 }
2110
2111 /****************************************************************************/
2112 /****************************TAP for SDP PROTOCOL ***************************/
2113 /****************************************************************************/
2114 /* whenever a SDP packet is seen by the tap listener */
2115 static int 
2116 SDPcalls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *SDPinfo)
2117 {
2118         voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
2119         const sdp_packet_info *pi = SDPinfo;
2120
2121         /* There are protocols like MGCP/SIP where the SDP is called before the tap for the
2122            MGCP/SIP packet, in those cases we assign the SPD summary to global lastSDPsummary
2123            to use it later 
2124         */
2125         g_free(sdp_summary);
2126         sdp_frame_num = pinfo->fd->num;
2127         /* Append to graph the SDP summary if the packet exists */
2128         sdp_summary = g_strdup_printf("SDP (%s)", pi->summary_str);
2129         append_to_frame_graph(tapinfo, pinfo->fd->num, sdp_summary, NULL);
2130
2131         tapinfo->redraw = TRUE;
2132
2133         return 1;  /* refresh output */
2134 }
2135
2136
2137 /****************************************************************************/
2138 /* TAP INTERFACE */
2139 /****************************************************************************/
2140 static gboolean have_sdp_tap_listener=FALSE;
2141 /****************************************************************************/
2142 void
2143 sdp_calls_init_tap(void)
2144 {
2145         GString *error_string;
2146
2147         if(have_sdp_tap_listener==FALSE)
2148         {
2149                 /* don't register tap listener, if we have it already */
2150                 error_string = register_tap_listener("sdp", &(the_tapinfo_struct.sdp_dummy), NULL,
2151                         voip_calls_dlg_reset, 
2152                         SDPcalls_packet, 
2153                         voip_calls_dlg_draw
2154                         );
2155                         
2156                 if (error_string != NULL) {
2157                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2158                                       error_string->str);
2159                         g_string_free(error_string, TRUE);
2160                         exit(1);
2161                 }
2162                 have_sdp_tap_listener=TRUE;
2163         }
2164 }
2165
2166 /****************************************************************************/
2167 void
2168 remove_tap_listener_sdp_calls(void)
2169 {
2170         protect_thread_critical_region();
2171         remove_tap_listener(&(the_tapinfo_struct.sdp_dummy));
2172         unprotect_thread_critical_region();
2173
2174         have_sdp_tap_listener=FALSE;
2175 }
2176
2177
2178
2179 /****************************************************************************/
2180 /* ***************************TAP for MGCP **********************************/
2181 /****************************************************************************/
2182
2183 /*
2184    This function will look for a signal/event in the SignalReq/ObsEvent string
2185    and return true if it is found 
2186 */
2187 static gboolean isSignal(const gchar *signal, const gchar *signalStr)
2188 {
2189         gint i; 
2190         gchar **resultArray;
2191         
2192         /* if there is no signalStr, just return false */
2193         if (signalStr == NULL) return FALSE;
2194
2195         /* if are both "blank" return true */
2196         if ( (*signal == '\0') &&  (*signalStr == '\0') ) return TRUE;
2197
2198         /* look for signal in signalSre */
2199         resultArray = g_strsplit(signalStr, ",", 10);
2200
2201         for (i = 0; resultArray[i]; i++) {
2202                 g_strstrip(resultArray[i]);
2203                 if (strcmp(resultArray[i], signal) == 0) return TRUE;
2204         }
2205
2206         g_strfreev(resultArray);
2207         
2208         return FALSE;
2209 }
2210
2211 /*
2212    This function will get the Caller ID info and replace the current string
2213    This is how it looks the caller Id: rg, ci(02/16/08/29, "3035550002","Ale Sipura 2")
2214 */
2215 static void mgcpCallerID(gchar *signalStr, gchar **callerId)
2216 {
2217         gchar **arrayStr;
2218         
2219         /* if there is no signalStr, just return false */
2220         if (signalStr == NULL) return;
2221
2222         arrayStr = g_strsplit(signalStr, "\"", 10);
2223
2224         if (arrayStr[0] == NULL) return;
2225
2226         /* look for the ci signal */
2227         if (strstr(arrayStr[0], "ci(") && (arrayStr[1] != NULL) ) {
2228                 /* free the previous "From" field of the call, and assign the new */
2229                 g_free(*callerId);
2230                 *callerId = g_strdup(arrayStr[1]);
2231         }
2232         g_strfreev(arrayStr);
2233
2234         return;
2235 }
2236
2237
2238 /*
2239    This function will get the Dialed Digits and replace the current string
2240    This is how it looks the dialed digits 5,5,5,0,0,0,2,#,*
2241 */
2242 static void mgcpDialedDigits(gchar *signalStr, gchar **dialedDigits)
2243 {
2244         gchar *tmpStr;
2245         gchar resultStr[50];
2246         gint i,j; 
2247
2248         /* if there is no signalStr, just return false */
2249         if (signalStr == NULL) return;
2250
2251         tmpStr = g_strdup(signalStr);
2252         
2253         for ( i = 0 ; tmpStr[i] ; i++) {
2254                 switch (tmpStr[i]) {
2255                         case '0' : case '1' : case '2' : case '3' : case '4' :
2256                         case '5' : case '6' : case '7' : case '8' : case '9' :
2257                         case '#' : case '*' :
2258                                 break;
2259                         default:
2260                                 tmpStr[i] = '?';
2261                                 break;
2262                 }
2263         }
2264         
2265         for (i = 0, j = 0; tmpStr[i] && i<50; i++) {
2266                 if (tmpStr[i] != '?')
2267                         resultStr[j++] = tmpStr[i];
2268         }
2269         resultStr[j] = '\0';
2270
2271         if (*resultStr == '\0') return;
2272         
2273         g_free(*dialedDigits);
2274         *dialedDigits = g_strdup(resultStr);
2275         g_free(tmpStr);
2276
2277         return;
2278 }
2279
2280
2281
2282 /****************************************************************************/
2283 /* whenever a MGCP packet is seen by the tap listener */
2284 static int 
2285 MGCPcalls_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *MGCPinfo)
2286 {
2287         voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
2288
2289         voip_calls_info_t *tmp_listinfo;
2290         voip_calls_info_t *strinfo = NULL;
2291         mgcp_calls_info_t *tmp_mgcpinfo = NULL;
2292         GList* list;
2293         GList* listGraph;
2294         gchar *frame_label = NULL;
2295         gchar *comment = NULL;
2296         graph_analysis_item_t *gai;
2297         gboolean new = FALSE;
2298         gboolean fromEndpoint = FALSE; /* true for calls originated in Endpoints, false for calls from MGC */
2299         gdouble diff_time;
2300
2301         const mgcp_info_t *pi = MGCPinfo;
2302
2303
2304         if ((pi->mgcp_type == MGCP_REQUEST) && !pi->is_duplicate ){
2305                 /* check whether we already have a call with this Endpoint and it is active*/
2306                 list = g_list_first(tapinfo->strinfo_list);
2307                 while (list)
2308                 {
2309                         tmp_listinfo=list->data;
2310                         if ((tmp_listinfo->protocol == VOIP_MGCP) && (tmp_listinfo->call_active_state == VOIP_ACTIVE)){
2311                                 tmp_mgcpinfo = tmp_listinfo->prot_info;
2312                                 if (pi->endpointId != NULL){
2313                                         if (g_strcasecmp(tmp_mgcpinfo->endpointId,pi->endpointId) == 0){
2314                                                 /*
2315                                                    check first if it is an ended call. We can still match packets to this Endpoint 2 seconds
2316                                                    after the call has been released
2317                                                 */
2318                                                 diff_time = nstime_to_sec(&pinfo->fd->rel_ts) - tmp_listinfo->stop_sec - (double)tmp_listinfo->stop_usec/1000000;
2319                                                 if ( ((tmp_listinfo->call_state == VOIP_CANCELLED) ||
2320                                                      (tmp_listinfo->call_state == VOIP_COMPLETED)  ||
2321                                                      (tmp_listinfo->call_state == VOIP_REJECTED)) &&
2322                                                        (diff_time > 2) )
2323                                                 {
2324                                                         tmp_listinfo->call_active_state = VOIP_INACTIVE;
2325                                                 } else {
2326                                                         strinfo = (voip_calls_info_t*)(list->data);
2327                                                         break;
2328                                                 }
2329                                         }
2330                                 }
2331                         }
2332                         list = g_list_next (list);
2333                 }
2334                 
2335                 /* there is no call with this Endpoint, lets see if this a new call or not */
2336                 if (strinfo == NULL){
2337                         if ( (strcmp(pi->code, "NTFY") == 0) && isSignal("hd", pi->observedEvents) ){ /* off hook transition */
2338                                 /* this is a new call from the Endpoint */      
2339                                 fromEndpoint = TRUE;
2340                                 new = TRUE;
2341                         } else if (strcmp(pi->code, "CRCX") == 0){
2342                                 /* this is a new call from the MGC */
2343                                 fromEndpoint = FALSE;
2344                                 new = TRUE;
2345                         }
2346                         if (!new) return 0;
2347                 } 
2348         } else if ( ((pi->mgcp_type == MGCP_RESPONSE) && pi->request_available) ||
2349                         ((pi->mgcp_type == MGCP_REQUEST) && pi->is_duplicate) ) {
2350                 /* if it is a response OR if it is a duplicated Request, lets look in the Graph to see
2351                    if there is a request that matches */
2352                 listGraph = g_list_first(tapinfo->graph_analysis->list);
2353                 while (listGraph)
2354                 {
2355                         gai = listGraph->data;
2356                         if (gai->frame_num == pi->req_num){
2357                                 /* there is a request that match, so look the associated call with this call_num */
2358                                 list = g_list_first(tapinfo->strinfo_list);
2359                                 while (list)
2360                                 {
2361                                         tmp_listinfo=list->data;
2362                                         if (tmp_listinfo->protocol == VOIP_MGCP){
2363                                                 if (tmp_listinfo->call_num == gai->conv_num){
2364                                                         tmp_mgcpinfo = tmp_listinfo->prot_info;
2365                                                         strinfo = (voip_calls_info_t*)(list->data);
2366                                                         break;
2367                                                 }
2368                                         }
2369                                         list = g_list_next (list);
2370                                 }
2371                                 if (strinfo != NULL) break;
2372                         }
2373                         listGraph = g_list_next(listGraph);
2374                 }
2375                 /* if there is not a matching request, just return */
2376                 if (strinfo == NULL) return 0;
2377         } else return 0;
2378
2379         /* not in the list? then create a new entry */
2380         if (strinfo==NULL){
2381                 strinfo = g_malloc(sizeof(voip_calls_info_t));
2382                 strinfo->call_active_state = VOIP_ACTIVE;
2383                 strinfo->call_state = VOIP_CALL_SETUP;
2384                 if (fromEndpoint) {
2385                         strinfo->from_identity=g_strdup(pi->endpointId);
2386                         strinfo->to_identity=g_strdup("");
2387                 } else {
2388                         strinfo->from_identity=g_strdup("");
2389                         strinfo->to_identity=g_strdup(pi->endpointId);
2390                 }
2391                 COPY_ADDRESS(&(strinfo->initial_speaker),&(pinfo->src));
2392                 strinfo->first_frame_num=pinfo->fd->num;
2393                 strinfo->selected=FALSE;
2394                 strinfo->start_sec=pinfo->fd->rel_ts.secs;
2395                 strinfo->start_usec=pinfo->fd->rel_ts.nsecs/1000;
2396                 strinfo->protocol=VOIP_MGCP;
2397                 strinfo->prot_info=g_malloc(sizeof(mgcp_calls_info_t));
2398                 tmp_mgcpinfo=strinfo->prot_info;
2399                 tmp_mgcpinfo->endpointId = g_strdup(pi->endpointId);
2400                 tmp_mgcpinfo->fromEndpoint = fromEndpoint;
2401                 strinfo->npackets = 0;
2402                 strinfo->call_num = tapinfo->ncalls++;
2403                 tapinfo->strinfo_list = g_list_append(tapinfo->strinfo_list, strinfo);
2404         }
2405
2406         g_assert(tmp_mgcpinfo != NULL);
2407
2408         /* change call state and add to graph */
2409         switch (pi->mgcp_type)
2410         {
2411         case MGCP_REQUEST:
2412                 if ( (strcmp(pi->code, "NTFY") == 0) && (pi->observedEvents != NULL) ){
2413                         frame_label = g_strdup_printf("%s ObsEvt:%s",pi->code, pi->observedEvents);
2414
2415                         if (tmp_mgcpinfo->fromEndpoint){
2416                                 /* use the Dialed digits to fill the "To" for the call, but use the first NTFY */
2417                                 if (strinfo->to_identity[0] == '\0') mgcpDialedDigits(pi->observedEvents, &(strinfo->to_identity));
2418
2419                         /* from MGC and the user picked up, the call is connected */
2420                         } else if (isSignal("hd", pi->observedEvents))  
2421                                 strinfo->call_state=VOIP_IN_CALL;
2422
2423                         /* hung up signal */
2424                         if (isSignal("hu", pi->observedEvents)) {
2425                                 if ((strinfo->call_state == VOIP_CALL_SETUP) || (strinfo->call_state == VOIP_RINGING)){
2426                                         strinfo->call_state = VOIP_CANCELLED;
2427                                 } else {
2428                                         strinfo->call_state = VOIP_COMPLETED;
2429                                 }
2430                         }       
2431                         
2432                 } else if (strcmp(pi->code, "RQNT") == 0) {
2433                         /* for calls from Endpoint: if there is a "no signal" RQNT and the call was RINGING, we assume this is the CONNECT */
2434                         if ( tmp_mgcpinfo->fromEndpoint && isSignal("", pi->signalReq) && (strinfo->call_state == VOIP_RINGING) ) { 
2435                                         strinfo->call_state = VOIP_IN_CALL;
2436                         }
2437
2438                         /* if there is ringback or ring tone, change state to ringing */
2439                         if ( isSignal("rg", pi->signalReq) || isSignal("rt", pi->signalReq) ) { 
2440                                         strinfo->call_state = VOIP_RINGING;
2441                         }
2442
2443                         /* if there is a Busy or ReorderTone, and the call was Ringing or Setup the call is Rejected */
2444                         if ( (isSignal("ro", pi->signalReq) || isSignal("bz", pi->signalReq)) && ((strinfo->call_state == VOIP_CALL_SETUP) || (strinfo->call_state = VOIP_RINGING)) ) { 
2445                                         strinfo->call_state = VOIP_REJECTED;
2446                         }
2447
2448                         if (pi->signalReq != NULL)
2449                                 frame_label = g_strdup_printf("%s%sSigReq:%s",pi->code, (pi->hasDigitMap == TRUE)?" DigitMap ":"", pi->signalReq);
2450                         else
2451                                 frame_label = g_strdup_printf("%s%s",pi->code, (pi->hasDigitMap == TRUE)?" DigitMap ":"");
2452                         
2453                         /* use the CallerID info to fill the "From" for the call */
2454                         if (!tmp_mgcpinfo->fromEndpoint) mgcpCallerID(pi->signalReq, &(strinfo->from_identity));
2455
2456                 } else if (strcmp(pi->code, "DLCX") == 0) {
2457                         /*
2458                           if there is a DLCX in a call To an Endpoint and the call was not connected, we use
2459                           the DLCX as the end of the call
2460                         */
2461                         if (!tmp_mgcpinfo->fromEndpoint){
2462                                 if ((strinfo->call_state == VOIP_CALL_SETUP) || (strinfo->call_state == VOIP_RINGING)){
2463                                         strinfo->call_state = VOIP_CANCELLED;
2464                                 } 
2465                         } 
2466                 }
2467
2468                 if (frame_label == NULL) frame_label = g_strdup_printf("%s",pi->code);
2469                 break;
2470         case MGCP_RESPONSE:
2471                 frame_label = g_strdup_printf("%u (%s)",pi->rspcode, pi->code);
2472                 break;
2473         case MGCP_OTHERS:
2474                 /* XXX what to do? */
2475                 break;
2476         }
2477
2478
2479         comment = g_strdup_printf("MGCP %s %s%s", tmp_mgcpinfo->endpointId, (pi->mgcp_type == MGCP_REQUEST)?"Request":"Response", pi->is_duplicate?" Duplicate":"");
2480
2481         strinfo->stop_sec=pinfo->fd->rel_ts.secs;
2482         strinfo->stop_usec=pinfo->fd->rel_ts.nsecs/1000;
2483         strinfo->last_frame_num=pinfo->fd->num;
2484         ++(strinfo->npackets);
2485         /* increment the packets counter of all calls */
2486         ++(tapinfo->npackets);
2487
2488         /* add to the graph */
2489         add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);  
2490         g_free(comment);
2491         g_free(frame_label);
2492
2493         /* add SDP info if apply */
2494         if ( (sdp_summary != NULL) && (sdp_frame_num == pinfo->fd->num) ){
2495                         append_to_frame_graph(tapinfo, pinfo->fd->num, sdp_summary, NULL);
2496                         g_free(sdp_summary);
2497                         sdp_summary = NULL;
2498         }
2499
2500         tapinfo->redraw = TRUE;
2501
2502         return 1;  /* refresh output */
2503 }
2504
2505
2506 /****************************************************************************/
2507 /* TAP INTERFACE */
2508 /****************************************************************************/
2509 static gboolean have_MGCP_tap_listener=FALSE;
2510 /****************************************************************************/
2511 void
2512 mgcp_calls_init_tap(void)
2513 {
2514         GString *error_string;
2515
2516         if(have_MGCP_tap_listener==FALSE)
2517         {
2518                 /* don't register tap listener, if we have it already */
2519                 /* we send an empty filter, to force a non null "tree" in the mgcp dissector */
2520                 error_string = register_tap_listener("mgcp", &(the_tapinfo_struct.mgcp_dummy), strdup(""),
2521                         voip_calls_dlg_reset, 
2522                         MGCPcalls_packet, 
2523                         voip_calls_dlg_draw
2524                         );
2525                 if (error_string != NULL) {
2526                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2527                                       error_string->str);
2528                         g_string_free(error_string, TRUE);
2529                         exit(1);
2530                 }
2531                 have_MGCP_tap_listener=TRUE;
2532         }
2533 }
2534
2535 /****************************************************************************/
2536 void
2537 remove_tap_listener_mgcp_calls(void)
2538 {
2539         protect_thread_critical_region();
2540         remove_tap_listener(&(the_tapinfo_struct.mgcp_dummy));
2541         unprotect_thread_critical_region();
2542
2543         have_MGCP_tap_listener=FALSE;
2544 }
2545
2546
2547 /****************************************************************************/
2548 /****************************TAP for ACTRACE (AudioCodes trace)**************/
2549 /****************************************************************************/
2550
2551 /* whenever a ACTRACE packet is seen by the tap listener */
2552 static int 
2553 ACTRACEcalls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *ACTRACEinfo)
2554 {
2555         voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
2556         const actrace_info_t *pi = ACTRACEinfo;
2557         GList *list;
2558         actrace_cas_calls_info_t *tmp_actrace_cas_info;
2559         voip_calls_info_t *tmp_listinfo;
2560         voip_calls_info_t *strinfo = NULL;
2561
2562
2563         actrace_frame_num = pinfo->fd->num;
2564         actrace_trunk = pi->trunk;
2565         actrace_direction = pi->direction;
2566
2567         if (pi->type == 1){ /* is CAS protocol */
2568                 address pstn_add;
2569                 gchar *comment = NULL;
2570
2571                 strinfo = NULL;
2572                 list = g_list_first(tapinfo->strinfo_list);
2573                 while (list)
2574                 {
2575                         tmp_listinfo=list->data;
2576                         if ( tmp_listinfo->protocol == VOIP_AC_CAS ){
2577                                 tmp_actrace_cas_info = tmp_listinfo->prot_info;
2578                                 /* TODO: Also check the IP of the Blade, and if the call is complete (no active) */
2579                                 if ( (tmp_actrace_cas_info->bchannel == pi->cas_bchannel) && (tmp_actrace_cas_info->trunk == actrace_trunk) ) {
2580                                         strinfo = (voip_calls_info_t*)(list->data);
2581                                         break;
2582                                 }
2583                         }
2584                         list = g_list_next (list);
2585                 }
2586
2587                 SET_ADDRESS(&pstn_add, AT_STRINGZ, 5, g_strdup("PSTN"));
2588
2589                 /* if it is a new call, add it to the list */
2590                 if (!strinfo) {
2591                         strinfo = g_malloc(sizeof(voip_calls_info_t));
2592                         strinfo->call_active_state = VOIP_ACTIVE;
2593                         strinfo->call_state = VOIP_CALL_SETUP;
2594                         strinfo->from_identity=g_strdup("N/A");
2595                         strinfo->to_identity=g_strdup("N/A");
2596                         COPY_ADDRESS(&(strinfo->initial_speaker),actrace_direction?&pstn_add:&(pinfo->src));
2597                         strinfo->first_frame_num=pinfo->fd->num;
2598                         strinfo->selected=FALSE;
2599                         strinfo->start_sec=pinfo->fd->rel_ts.secs;
2600                         strinfo->start_usec=pinfo->fd->rel_ts.nsecs/1000;
2601                         strinfo->protocol=VOIP_AC_CAS;
2602                         strinfo->prot_info=g_malloc(sizeof(actrace_cas_calls_info_t));
2603                         tmp_actrace_cas_info=strinfo->prot_info;
2604                         tmp_actrace_cas_info->bchannel=pi->cas_bchannel;
2605                         tmp_actrace_cas_info->trunk=actrace_trunk;
2606                         strinfo->npackets = 0;
2607                         strinfo->call_num = tapinfo->ncalls++;
2608                         tapinfo->strinfo_list = g_list_append(tapinfo->strinfo_list, strinfo);
2609                 }
2610
2611                 strinfo->stop_sec=pinfo->fd->rel_ts.secs;
2612                 strinfo->stop_usec=pinfo->fd->rel_ts.nsecs/1000;
2613                 strinfo->last_frame_num=pinfo->fd->num;
2614                 ++(strinfo->npackets);
2615                 /* increment the packets counter of all calls */
2616                 ++(tapinfo->npackets);
2617
2618                 if (!comment)
2619                         comment = g_strdup_printf("AC_CAS  trunk:%u", actrace_trunk );
2620
2621                 add_to_graph(tapinfo, pinfo, pi->cas_frame_label , comment, strinfo->call_num, 
2622                                 actrace_direction?&pstn_add:&(pinfo->src),
2623                                 actrace_direction?&(pinfo->src):&pstn_add,
2624                                 1 );
2625
2626                 g_free(comment);
2627                 g_free((char *)pstn_add.data);
2628         }
2629
2630         tapinfo->redraw = TRUE;
2631
2632         return 1;  /* refresh output */
2633 }
2634
2635
2636 /****************************************************************************/
2637 /* TAP INTERFACE */
2638 /****************************************************************************/
2639 static gboolean have_actrace_tap_listener=FALSE;
2640 /****************************************************************************/
2641 void
2642 actrace_calls_init_tap(void)
2643 {
2644         GString *error_string;
2645
2646         if(have_actrace_tap_listener==FALSE)
2647         {
2648                 /* don't register tap listener, if we have it already */
2649                 error_string = register_tap_listener("actrace", &(the_tapinfo_struct.actrace_dummy), NULL,
2650                         voip_calls_dlg_reset, 
2651                         ACTRACEcalls_packet, 
2652                         voip_calls_dlg_draw
2653                         );
2654                         
2655                 if (error_string != NULL) {
2656                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2657                                       error_string->str);
2658                         g_string_free(error_string, TRUE);
2659                         exit(1);
2660                 }
2661                 have_actrace_tap_listener=TRUE;
2662         }
2663 }
2664
2665 /****************************************************************************/
2666 void
2667 remove_tap_listener_actrace_calls(void)
2668 {
2669         protect_thread_critical_region();
2670         remove_tap_listener(&(the_tapinfo_struct.actrace_dummy));
2671         unprotect_thread_critical_region();
2672
2673         have_actrace_tap_listener=FALSE;
2674 }
2675
2676 /****************************************************************************/
2677 /* ***************************TAP for OTHER PROTOCOL **********************************/
2678 /****************************************************************************/
2679
2680 /****************************************************************************/
2681 /* whenever a prot_ packet is seen by the tap listener */
2682 /*
2683 static int 
2684 prot_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *prot_info _U_)
2685 {
2686         voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
2687         if (strinfo!=NULL){
2688                 strinfo->stop_sec=pinfo->fd->rel_secs;
2689                 strinfo->stop_usec=pinfo->fd->rel_usecs;
2690                 strinfo->last_frame_num=pinfo->fd->num;
2691                 ++(strinfo->npackets);
2692                 ++(tapinfo->npackets);
2693         }
2694
2695         tapinfo->redraw = TRUE;
2696
2697         return 1;
2698 }
2699 */
2700 /****************************************************************************/
2701 /*
2702 static gboolean have_prot__tap_listener=FALSE;
2703
2704 void
2705 prot_calls_init_tap(void)
2706 {
2707         GString *error_string;
2708
2709         if(have_prot__tap_listener==FALSE)
2710         {
2711                 error_string = register_tap_listener("prot_", &(the_tapinfo_struct.prot__dummy),
2712                         NULL,
2713                         voip_calls_dlg_reset,
2714                         prot__calls_packet, 
2715                         voip_calls_dlg_draw
2716                         );
2717
2718                 if (error_string != NULL) {
2719                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2720                                       error_string->str);
2721                         g_string_free(error_string, TRUE);
2722                         exit(1);
2723                 }
2724                 have_prot__tap_listener=TRUE;
2725         }
2726 }
2727 */
2728 /****************************************************************************/
2729 /*
2730 void
2731 remove_tap_listener_prot__calls(void)
2732 {
2733         protect_thread_critical_region();
2734         remove_tap_listener(&(the_tapinfo_struct.prot__dummy));
2735         unprotect_thread_critical_region();
2736
2737         have_prot__tap_listener=FALSE;
2738 }
2739 */