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