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