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